ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-10-20 05:13:23
Exec Total Coverage
Lines: 4199 5245 80.1%
Functions: 295 334 88.3%
Branches: 3250 5314 61.2%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 425 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 425 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 606 void maps_init_game_vars()
67 {
68 606 viewport = {};
69 606 viewport_mode = ViewportMode::CenterAndBound;
70 606 viewport_sprite_uid = 1;
71 606 currscr_for_passive_subscr = -1;
72 606 }
73
74 static region_ids_t current_region_ids;
75
76 // Returns true if the (map, screen) is inside a scrolling region.
77 15146473 static bool is_in_scrolling_region(int map, int screen)
78 {
79 15146473 return get_region_id(map, screen) != 0;
80 }
81
82 bool is_in_screenscrolling_region(int screen)
83 {
84 if (!screenscrolling) return false;
85
86 int x = screen % 16;
87 int y = screen / 16;
88 return
89 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
90 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
91 }
92
93 9002973923 bool is_in_scrolling_region()
94 {
95 9002973923 return cur_region.screen_count > 1;
96 }
97
98 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
99 {
100
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_in_scrolling_region(map, scr)) return false;
101 1460 int region_id = get_region_id(map, region_origin_scr);
102
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
103 2232 }
104
105 251223879 bool is_in_current_region(int map, int screen)
106 {
107
2/2
✓ Branch 0 taken 1598 times.
✓ Branch 1 taken 251222281 times.
251223879 if (map != cur_map)
108 1598 return false;
109
110
3/4
✓ Branch 0 taken 251222281 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 251210068 times.
✓ Branch 3 taken 12213 times.
251222281 if (screen >= 0 && screen < 128)
111 251210068 return screen_in_current_region[screen];
112
113 12213 return screen == cur_screen;
114 251223879 }
115
116 244725895 bool is_in_current_region(int screen)
117 {
118
5/6
✓ Branch 0 taken 243610277 times.
✓ Branch 1 taken 1115618 times.
✓ Branch 2 taken 1115618 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1115613 times.
244725895 return screen == cur_screen || (screen >= 0 && screen < 128 && screen_in_current_region[screen]);
119 }
120
121 30760835 bool is_in_current_region(mapscr* scr)
122 {
123
2/2
✓ Branch 0 taken 14690 times.
✓ Branch 1 taken 30746145 times.
30760835 return scr->map == cur_map && is_in_current_region(scr->screen);
124 }
125
126 63773989 bool is_extended_height_mode()
127 {
128
2/2
✓ Branch 0 taken 63574541 times.
✓ Branch 1 taken 199448 times.
63773989 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
129 }
130
131 // Returns 0 if this is not a scrolling region.
132 42485265 int get_region_id(int map, int screen)
133 {
134
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 42083830 times.
42485265 if (screen >= 128) return 0;
135
2/2
✓ Branch 0 taken 42082706 times.
✓ Branch 1 taken 1124 times.
42083830 if (map == cur_region.map) return current_region_ids[screen];
136
137 1124 return Regions[map].get_region_id(screen);
138 42485265 }
139
140 27276802 int get_current_region_id()
141 {
142 27276802 return get_region_id(cur_map, cur_screen);
143 }
144
145 67242 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
146 {
147 67242 region.map = map;
148
149
2/2
✓ Branch 0 taken 66968 times.
✓ Branch 1 taken 274 times.
67242 if (!is_in_scrolling_region(map, screen))
150 {
151 66968 region.region_id = 0;
152 66968 region.origin_screen = screen;
153 66968 region.origin_screen_x = screen % 16;
154 66968 region.origin_screen_y = screen / 16;
155 66968 region.screen_width = 1;
156 66968 region.screen_height = 1;
157 66968 region.screen_count = 1;
158 66968 region.width = 256;
159 66968 region.height = 176;
160 66968 region_scr_dx = 0;
161 66968 region_scr_dy = 0;
162 66968 return;
163 }
164
165 274 int input_scr_x = screen % 16;
166 274 int input_scr_y = screen / 16;
167
168 // For the given screen, find the top-left corner of its region.
169 274 int origin_scr_x = input_scr_x;
170 274 int origin_scr_y = input_scr_y;
171 274 int origin_scr = screen;
172
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
173 {
174
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
175 160 origin_scr_x--;
176 }
177
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
178 {
179
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
180 234 origin_scr_y--;
181 }
182 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
183
184 // Now find the bottom-right corner.
185 274 int region_scr_right = origin_scr_x;
186
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
187 {
188
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
189 368 region_scr_right++;
190 }
191 274 int region_scr_bottom = origin_scr_y;
192
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
193 {
194
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
195 582 region_scr_bottom++;
196 }
197
198 274 region.region_id = get_region_id(map, origin_scr);
199 274 region.origin_screen = origin_scr;
200 274 region.origin_screen_x = origin_scr_x;
201 274 region.origin_screen_y = origin_scr_y;
202 274 region.screen_width = region_scr_right - origin_scr_x + 1;
203 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
204 274 region.screen_count = region.screen_width * region.screen_height;
205 274 region.width = 256 * region.screen_width;
206 274 region.height = 176 * region.screen_height;
207 274 region_scr_dx = input_scr_x - origin_scr_x;
208 274 region_scr_dy = input_scr_y - origin_scr_y;
209
210 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
211 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
212 67242 }
213
214 37528 void load_region(int dmap, int screen)
215 {
216 37528 clear_temporary_screens();
217
218 37528 int map = DMaps[dmap].map;
219 37528 current_region_ids = Regions[map].get_all_region_ids();
220
221 37528 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
222 37528 cur_screen = cur_region.origin_screen;
223 37528 world_w = cur_region.width;
224 37528 world_h = cur_region.height;
225 37528 region_scr_count = cur_region.screen_count;
226 37528 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
227 37528 region_num_rpos = cur_region.screen_count*176;
228 37528 scrolling_maze_last_solved_screen = 0;
229
230 37528 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
231
2/2
✓ Branch 0 taken 37762 times.
✓ Branch 1 taken 37528 times.
75290 for (int x = 0; x < cur_region.screen_width; x++)
232 {
233
2/2
✓ Branch 0 taken 38772 times.
✓ Branch 1 taken 37762 times.
76534 for (int y = 0; y < cur_region.screen_height; y++)
234 {
235 38772 int screen = cur_screen + x + y*16;
236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38772 times.
38772 if (screen < 136)
237 {
238 38772 screen_in_current_region[screen] = true;
239 38772 }
240 38772 }
241 37762 }
242
243 37528 mark_current_region_handles_dirty();
244 37528 }
245
246 37528 static void prepare_current_region_handles()
247 {
248 37528 current_region_rpos_handles_dirty = false;
249 37528 current_region_screen_count = 0;
250
2/2
✓ Branch 0 taken 37876 times.
✓ Branch 1 taken 37528 times.
75404 for (int y = 0; y < cur_region.screen_height; y++)
251 {
252
2/2
✓ Branch 0 taken 38772 times.
✓ Branch 1 taken 37876 times.
76648 for (int x = 0; x < cur_region.screen_width; x++)
253 {
254 38772 int screen = cur_screen + x + y*16;
255 38772 int index_start = current_region_screen_count;
256
2/2
✓ Branch 0 taken 38772 times.
✓ Branch 1 taken 271404 times.
310176 for (int layer = 0; layer <= 6; layer++)
257 {
258 271404 mapscr* scr = get_scr_layer(screen, layer);
259
2/2
✓ Branch 0 taken 95241 times.
✓ Branch 1 taken 176163 times.
271404 if (!scr->is_valid())
260 {
261
1/2
✓ Branch 0 taken 176163 times.
✗ Branch 1 not taken.
176163 if (layer == 0) break;
262 176163 continue;
263 }
264
265 95241 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
266 95241 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
267 95241 current_region_screen_count += 1;
268 95241 }
269
270 38772 int num_handles_for_scr = current_region_screen_count - index_start;
271 38772 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
272 38772 }
273 37876 }
274 37528 }
275
276 1814511495 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
277 {
278 DCHECK(!current_region_rpos_handles_dirty);
279 1814511495 return {current_region_rpos_handles, current_region_screen_count};
280 }
281
282 11479980 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
283 {
284 DCHECK(!current_region_rpos_handles_dirty);
285
2/4
✓ Branch 0 taken 11479980 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11479980 times.
11479980 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
286 return {nullptr, 0};
287
288
2/2
✓ Branch 0 taken 65877 times.
✓ Branch 1 taken 11414103 times.
11479980 if (cur_screen >= 0x80)
289 {
290 DCHECK(scr == origin_scr);
291 65877 return {nullptr, 0};
292 }
293
294 DCHECK(is_in_current_region(scr));
295 11414103 return current_region_rpos_handles_scr[scr->screen];
296 11479980 }
297
298 37528 void mark_current_region_handles_dirty()
299 {
300 37528 current_region_rpos_handles_dirty = true;
301 37528 }
302
303 67999 void delete_temporary_screens(mapscr** screens)
304 {
305
2/2
✓ Branch 0 taken 64735048 times.
✓ Branch 1 taken 67999 times.
64803047 for (int i = 0; i < 136*7; i++)
306 {
307
2/2
✓ Branch 0 taken 267351 times.
✓ Branch 1 taken 64467697 times.
64735048 if (!screens[i])
308 64467697 continue;
309
310 267351 mapscr* scr = screens[i];
311 267351 int num_ffcs = scr->numFFC();
312
2/2
✓ Branch 0 taken 7621503 times.
✓ Branch 1 taken 267351 times.
7888854 for (int i = 0; i < num_ffcs; i++)
313 {
314 7621503 sprite* ffc = &scr->ffcs[i];
315
2/2
✓ Branch 0 taken 7617968 times.
✓ Branch 1 taken 3535 times.
7621503 if (ffc->uid)
316 3535 FFCore.release_sprite_owned_objects(ffc->uid);
317 7621503 }
318
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 267351 times.
267351 delete scr;
319 267351 screens[i] = NULL;
320 267351 }
321 67999 }
322
323 38696 void clear_temporary_screens()
324 {
325 38696 delete_temporary_screens(temporary_screens);
326 38696 origin_scr = nullptr;
327 38696 hero_scr = nullptr;
328 38696 }
329
330 29307 std::vector<mapscr*> take_temporary_scrs()
331 {
332
1/2
✓ Branch 0 taken 29307 times.
✗ Branch 1 not taken.
29307 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
333
2/2
✓ Branch 0 taken 29307 times.
✓ Branch 1 taken 27900264 times.
27929571 for (int i = 0; i < 136*7; i++)
334 27900264 temporary_screens[i] = nullptr;
335
336 29307 return screens;
337
1/2
✓ Branch 0 taken 29307 times.
✗ Branch 1 not taken.
29307 }
338
339 15077359 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
340 {
341 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
342
343
2/2
✓ Branch 0 taken 15030777 times.
✓ Branch 1 taken 46582 times.
15077359 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
344 15077359 viewport.w = 256;
345 15077359 viewport.h = 176 + (extended_height_mode ? 56 : 0);
346
347
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 15076999 times.
15077359 if (viewport_mode == ViewportMode::Script)
348 360 return;
349
350
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 15030837 times.
15076999 if (!is_in_scrolling_region(DMaps[dmap].map, screen))
351 {
352 15030837 viewport.x = 0;
353 15030837 viewport.y = 0;
354 15030837 }
355
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
356 {
357 // Clamp the viewport to the edges of the region.
358
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
359
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
360 46162 }
361 else if (viewport_mode == ViewportMode::Center)
362 {
363 viewport.x = x - viewport.w/2;
364 viewport.y = y - viewport.h/2;
365 }
366 15077359 }
367
368 15076848 sprite* get_viewport_sprite()
369 {
370 15076848 sprite* spr = sprite::getByUID(viewport_sprite_uid);
371
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 15076842 times.
15076848 if (!spr)
372 {
373 6 viewport_sprite_uid = 1; // Hero uid.
374 6 spr = &Hero;
375 6 }
376
377 15076848 return spr;
378 }
379
380 6 void set_viewport_sprite(sprite* spr)
381 {
382 6 viewport_sprite_uid = spr->uid;
383 6 }
384
385 15047541 void update_viewport()
386 {
387 15047541 sprite* spr = get_viewport_sprite();
388 15047541 int x = spr->x + spr->txsz*16/2;
389 15047541 int y = spr->y + spr->tysz*16/2;
390 15047541 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
391 15047541 }
392
393 // TODO: should add a moveflag to sprites to configure the size of this rect (or effectively disable
394 // freezing if the rect returns is large enough). See:
395 // https://discord.com/channels/876899628556091432/1358483603700449581
396 // https://discord.com/channels/876899628556091432/1130384911983980554
397 //
398 89021260 viewport_t get_sprite_freeze_rect()
399 {
400 89021260 viewport_t freeze_rect = viewport;
401 89021260 int tile_buffer = 3;
402 89021260 freeze_rect.w += 16 * tile_buffer * 2;
403 89021260 freeze_rect.h += 16 * tile_buffer * 2;
404 89021260 freeze_rect.x -= 16 * tile_buffer;
405 89021260 freeze_rect.y -= 16 * tile_buffer;
406 89021260 return freeze_rect;
407 }
408
409 4722 mapscr* determine_hero_screen_from_coords()
410 {
411 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
412 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
413 4722 int dx = x / 256;
414 4722 int dy = y / 176;
415 4722 return get_scr(cur_screen + dx + dy * 16);
416 }
417
418 28218 bool edge_of_region(direction dir)
419 {
420
2/2
✓ Branch 0 taken 28138 times.
✓ Branch 1 taken 80 times.
28218 if (!is_in_scrolling_region()) return true;
421
422 80 int screen_x = Hero.current_screen % 16;
423 80 int screen_y = Hero.current_screen / 16;
424
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
425
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
426
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
427
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
428
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
429 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
430 28218 }
431
432 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
433 // Coordinates are clamped to the world bounds.
434 338073428 int get_screen_for_world_xy(int x, int y)
435 {
436
2/2
✓ Branch 0 taken 316934404 times.
✓ Branch 1 taken 21139024 times.
338073428 if (!is_in_scrolling_region())
437 316934404 return cur_screen;
438
439 21139024 int dx = std::clamp(x, 0, world_w - 1) / 256;
440 21139024 int dy = std::clamp(y, 0, world_h - 1) / 176;
441 21139024 int origin_screen_x = cur_screen % 16;
442 21139024 int origin_screen_y = cur_screen / 16;
443 21139024 int scr_x = origin_screen_x + dx;
444 21139024 int scr_y = origin_screen_y + dy;
445 21139024 return map_scr_xy_to_index(scr_x, scr_y);
446 338073428 }
447
448 31102071 int get_screen_for_rpos(rpos_t rpos)
449 {
450 31102071 int origin_screen_x = cur_screen % 16;
451 31102071 int origin_screen_y = cur_screen / 16;
452 31102071 int screen = static_cast<int32_t>(rpos) / 176;
453 31102071 int scr_x = origin_screen_x + screen%cur_region.screen_width;
454 31102071 int scr_y = origin_screen_y + screen/cur_region.screen_width;
455 31102071 return map_scr_xy_to_index(scr_x, scr_y);
456 }
457
458 837196324 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
459 {
460 DCHECK_LAYER_ZERO_INDEX(layer);
461
2/2
✓ Branch 0 taken 806232216 times.
✓ Branch 1 taken 30964108 times.
837196324 if (!is_in_scrolling_region())
462 806232216 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
463 30964108 int screen = get_screen_for_rpos(rpos);
464 30964108 mapscr* scr = get_scr_layer(screen, layer);
465 30964108 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
466 837196324 }
467
468 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
469 // Coordinates are clamped to the world bounds.
470 3484529889 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
471 {
472 3484529889 x = std::clamp(x, 0, world_w - 1);
473 3484529889 y = std::clamp(y, 0, world_h - 1);
474
475 DCHECK_LAYER_ZERO_INDEX(layer);
476
2/2
✓ Branch 0 taken 3458187411 times.
✓ Branch 1 taken 26342478 times.
3484529889 if (!is_in_scrolling_region())
477 {
478 3458187411 int pos = COMBOPOS(x, y);
479 3458187411 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
480 }
481 26342478 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
482 3484529889 }
483
484 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
485 1926 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
486 {
487 DCHECK_LAYER_ZERO_INDEX(layer);
488 1926 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
489 }
490
491 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
492 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
493 63140 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
494 {
495 DCHECK_LAYER_ZERO_INDEX(layer);
496 63140 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
497 }
498
499 25577031 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
500 {
501 DCHECK_LAYER_ZERO_INDEX(layer);
502 25577031 rpos_handle.layer = layer;
503 25577031 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
504 25577031 }
505
506 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
507 // Coordinates are clamped to the world bounds.
508 86712 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
509 {
510 DCHECK_LAYER_ZERO_INDEX(layer);
511
512 86712 x = std::clamp(x, 0, world_w - 1);
513 86712 y = std::clamp(y, 0, world_h - 1);
514
515 86712 auto maybe_ffc_handle = getFFCAt(x, y);
516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86712 times.
86712 if (maybe_ffc_handle)
517 return maybe_ffc_handle.value();
518
519 86712 auto rpos = COMBOPOS_REGION_B(x, y);
520
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 86712 times.
86712 if (rpos == rpos_t::None)
521 return rpos_handle_t();
522 86712 return get_rpos_handle(rpos, layer);
523 86712 }
524
525 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
526 // directly or via zscript) only last until the next area is loaded (via loadscr).
527
528 // Returns the screen containing the (x, y) world position.
529 1555053454 mapscr* get_scr_for_world_xy(int x, int y)
530 {
531 // Quick path, but should work the same without.
532
2/2
✓ Branch 0 taken 1544614054 times.
✓ Branch 1 taken 10439400 times.
1555053454 if (!is_in_scrolling_region()) return origin_scr;
533 10439400 return get_scr(get_screen_for_world_xy(x, y));
534 1555053454 }
535
536 25994166 mapscr* get_scr_for_rpos(rpos_t rpos)
537 {
538 // Quick path, but should work the same without.
539
2/2
✓ Branch 0 taken 25856220 times.
✓ Branch 1 taken 137946 times.
25994166 if (!is_in_scrolling_region()) return origin_scr;
540 137946 return get_scr(get_screen_for_rpos(rpos));
541 25994166 }
542
543 17 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
544 {
545 17 return get_scr_layer(get_screen_for_rpos(rpos), layer);
546 }
547
548 // Note: layer=0 is the base screen, 1 is the first layer, etc.
549 2135356359 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
550 {
551 DCHECK_LAYER_ZERO_INDEX(layer);
552
2/2
✓ Branch 0 taken 2125311145 times.
✓ Branch 1 taken 10045214 times.
2135356359 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
553
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 9336280 times.
10045214 return layer == 0 ?
554 708934 get_scr_for_world_xy(x, y) :
555 9336280 get_scr_layer(get_screen_for_world_xy(x, y), layer);
556 2135356359 }
557
558 1857170545 int get_region_screen_offset(int screen)
559 {
560 1857170545 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
561 }
562
563 655240230 int get_screen_for_region_index_offset(int offset)
564 {
565 655240230 int scr_dx = offset % cur_region.screen_width;
566 655240230 int scr_dy = offset / cur_region.screen_width;
567 655240230 int screen = cur_screen + scr_dx + scr_dy*16;
568 655240230 return screen;
569 }
570
571 655056392 mapscr* get_scr_for_region_index_offset(int offset)
572 {
573 655056392 int screen = get_screen_for_region_index_offset(offset);
574 655056392 return get_scr(screen);
575 }
576
577 // The screen at (map, screen) must exist.
578 1541113360 mapscr* get_scr(int map, int screen)
579 {
580 1541113360 mapscr* scr = get_scr_maybe(map, screen);
581
1/2
✓ Branch 0 taken 1541113360 times.
✗ Branch 1 not taken.
1541113360 CHECK(scr);
582 1541113360 return scr;
583 }
584
585 841635775 mapscr* get_scr(int screen)
586 {
587 841635775 return get_scr(cur_map, screen);
588 }
589
590 // Returns null if active screen does not exist.
591 1726949018 mapscr* get_scr_maybe(int map, int screen)
592 {
593 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
594
595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1726949018 times.
1726949018 if (map == cur_map)
596 {
597
2/2
✓ Branch 0 taken 1706123044 times.
✓ Branch 1 taken 20825974 times.
1726949018 if (screen == cur_screen)
598 1706123044 return origin_scr;
599
600 20825974 int index = screen*7;
601
2/2
✓ Branch 0 taken 20802272 times.
✓ Branch 1 taken 23702 times.
20825974 if (temporary_screens[index])
602 20802272 return temporary_screens[index];
603
604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23702 times.
23702 if (screen == home_screen)
605 return special_warp_return_scr;
606 23702 }
607
608
4/6
✓ Branch 0 taken 23700 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 23700 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 23700 times.
23702 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
609 {
610 23700 int index = screen*7;
611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23700 times.
23700 if (FFCore.ScrollingScreensAll[index])
612 23700 return FFCore.ScrollingScreensAll[index];
613 }
614
615 2 return nullptr;
616 1726949018 }
617
618 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
619 6986153731 mapscr* get_scr_layer(int map, int screen, int layer)
620 {
621 DCHECK_LAYER_ZERO_INDEX(layer);
622
2/2
✓ Branch 0 taken 6289614762 times.
✓ Branch 1 taken 696538969 times.
6986153731 if (layer == 0)
623 696538969 return get_scr(map, screen);
624
625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6289614762 times.
6289614762 if (map == cur_map)
626 {
627 6289614762 int index = screen*7 + layer;
628
2/2
✓ Branch 0 taken 6289470702 times.
✓ Branch 1 taken 144060 times.
6289614762 if (temporary_screens[index])
629 6289470702 return temporary_screens[index];
630
631
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 142200 times.
144060 if (screen == home_screen)
632 1860 return &special_warp_return_scrs[layer];
633 142200 }
634
635
1/2
✓ Branch 0 taken 142200 times.
✗ Branch 1 not taken.
142200 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
636 {
637 142200 int index = screen*7 + layer;
638
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142200 times.
142200 if (FFCore.ScrollingScreensAll[index])
639 142200 return FFCore.ScrollingScreensAll[index];
640 }
641
642 NOTREACHED();
643 6986153731 }
644
645 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
646 6564134719 mapscr* get_scr_layer(int screen, int layer)
647 {
648 6564134719 return get_scr_layer(cur_map, screen, layer);
649 }
650
651 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
652 // Return nullptr if screen is not valid.
653 419038655 mapscr* get_scr_layer_valid(int screen, int layer)
654 {
655
2/2
✓ Branch 0 taken 98840427 times.
✓ Branch 1 taken 320198228 times.
419038655 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
656 98840427 return scr;
657 320198228 return nullptr;
658 419038655 }
659
660 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
661 {
662 401 int x = get_region_relative_dx(screen);
663 401 int y = get_region_relative_dy(screen);
664
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
665 71 return nullptr;
666
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
667 return nullptr;
668
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
669 return nullptr;
670
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
671 189 return nullptr;
672
673 141 screen = screen_index_direction(screen, dir);
674
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
675 return get_scr(screen);
676
677 141 return nullptr;
678 401 }
679
680 183838 ffc_handle_t get_ffc_handle(ffc_id_t id)
681 {
682 183838 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
683 183838 uint8_t i = id % MAXFFCS;
684 183838 mapscr* scr = get_scr(screen);
685 183838 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
686 183838 return {scr, screen, id, i, ffc};
687 }
688
689 34571 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
690 {
691 34571 x += get_region_relative_dx(screen) * 256;
692 34571 y += get_region_relative_dy(screen) * 176;
693 34571 return {x, y};
694 }
695
696 1056037 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
697 {
698 1056037 int x = get_region_relative_dx(screen) * 256;
699 1056037 int y = get_region_relative_dy(screen) * 176;
700 1056037 return {x, y};
701 }
702
703 12688797625 int32_t COMBOPOS(int32_t x, int32_t y)
704 {
705 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
706 12688797625 return (y & 0xF0) + (x >> 4);
707 }
708 int32_t COMBOPOS_B(int32_t x, int32_t y)
709 {
710 if(unsigned(x) >= 256 || unsigned(y) >= 176)
711 return -1;
712 return (y & 0xF0) + (x >> 4);
713 }
714 3953286298 int32_t COMBOX(int32_t pos)
715 {
716 3953286298 return pos % 16 * 16;
717 }
718 3953286298 int32_t COMBOY(int32_t pos)
719 {
720 3953286298 return pos & 0xF0;
721 }
722
723 116957819 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
724 {
725
2/2
✓ Branch 0 taken 89799867 times.
✓ Branch 1 taken 27157952 times.
116957819 if (!is_in_scrolling_region())
726 89799867 return (rpos_t) COMBOPOS(x, y);
727
728 DCHECK(is_in_world_bounds(x, y));
729 27157952 int scr_dx = x / (16*16);
730 27157952 int scr_dy = y / (11*16);
731 27157952 int pos = COMBOPOS(x%256, y%176);
732 27157952 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
733 116957819 }
734 6958615415 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
735 {
736
2/2
✓ Branch 0 taken 1553141 times.
✓ Branch 1 taken 6957062274 times.
6958615415 if (!is_in_world_bounds(x, y))
737 1553141 return rpos_t::None;
738
739 6957062274 int scr_dx = x / (16*16);
740 6957062274 int scr_dy = y / (11*16);
741 6957062274 int pos = COMBOPOS(x%256, y%176);
742 6957062274 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
743 6958615415 }
744 28725538 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
745 {
746 28725538 int scr_index = static_cast<int32_t>(rpos) / 176;
747 28725538 int scr_dx = scr_index % cur_region.screen_width;
748 28725538 int scr_dy = scr_index / cur_region.screen_width;
749 28725538 int pos = RPOS_TO_POS(rpos);
750 28725538 int x = scr_dx*16*16 + COMBOX(pos);
751 28725538 int y = scr_dy*11*16 + COMBOY(pos);
752 28725538 return {x, y};
753 }
754 182363 int32_t COMBOX_REGION(rpos_t rpos)
755 {
756 182363 auto [x, y] = COMBOXY_REGION(rpos);
757 182363 return x;
758 }
759 134192 int32_t COMBOY_REGION(rpos_t rpos)
760 {
761 134192 auto [x, y] = COMBOXY_REGION(rpos);
762 134192 return y;
763 }
764
765 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
766 {
767 DCHECK(is_in_world_bounds(x, y));
768
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
769 70177 return (rpos_t)(x + y * 16);
770
771 int scr_dx = x / 16;
772 int scr_dy = y / 11;
773 x %= 16;
774 y %= 11;
775 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
776 70177 }
777 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
778 {
779 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
780 70632 int scr_dx = scr_index % cur_region.screen_width;
781 70632 int scr_dy = scr_index / cur_region.screen_width;
782 70632 int pos = RPOS_TO_POS(rpos);
783 70632 int x = scr_dx*16 + pos%16;
784 70632 int y = scr_dy*11 + pos/16;
785 70632 return {x, y};
786 }
787
788 92306204 int32_t mapind(int32_t map, int32_t scr)
789 {
790 92306204 return map * MAPSCRSNORMAL + scr;
791 }
792
793 FONT *get_zc_font(int index);
794
795 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
796 extern movingblock mblock2; //mblock[4]?
797 extern portal mirror_portal;
798
799 void Z_message_d(const char *format,...)
800 {
801 #ifdef _DEBUG
802 char buf[512];
803 va_list ap;
804 va_start(ap, format);
805 vsprintf(buf, format, ap);
806 va_end(ap);
807
808 al_trace("%s",buf);
809 #else
810 format=format;
811 #endif
812 }
813
814
815
816 bool checktrigger=false;
817
818 void debugging_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
819 {
820 //reference/optimization: the start of the unused drawing command index can now be queried. -Gleeok
821 int32_t index = script_drawing_commands.GetNext();
822
823 if(index < 0)
824 return;
825
826 int32_t *sdci = &script_drawing_commands[index][0];
827
828 sdci[0] = RECTR;
829 sdci[1] = 30000;
830 sdci[2] = x1*10000;
831 sdci[3] = y1*10000;
832 sdci[4] = x2*10000;
833 sdci[5] = y2*10000;
834 sdci[6] = 10000;
835 sdci[7] = 10000;
836 sdci[8] = 0;
837 sdci[9] = 0;
838 sdci[10] = 0;
839 sdci[11] = 10000;
840 sdci[12] = 1280000;
841 }
842
843 void clear_dmap(word i)
844 {
845 DMaps[i].clear();
846 }
847
848 void clear_dmaps()
849 {
850 for(int32_t i=0; i<MAXDMAPS; i++)
851 {
852 clear_dmap(i);
853 }
854 }
855
856 235185711 int32_t isdungeon(int32_t dmap, int32_t screen)
857 {
858
2/2
✓ Branch 0 taken 235138351 times.
✓ Branch 1 taken 47360 times.
235185711 if (dmap < 0) dmap = cur_dmap;
859
860 // dungeons can have any dlevel above 0
861
2/2
✓ Branch 0 taken 133936266 times.
✓ Branch 1 taken 101249445 times.
235185711 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
862 {
863
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101239484 times.
101249445 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
864 9961 return 0;
865
866 101239484 return 1;
867 }
868
869 // dlevels that aren't dungeons are caves
870
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 133899439 times.
133936266 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
871 36827 return 1;
872
873 133899439 return 0;
874 235185711 }
875
876 43125315 int32_t isdungeon(int32_t screen)
877 {
878 43125315 return isdungeon(cur_dmap, screen);
879 }
880
881 191928260 int32_t isdungeon()
882 {
883 191928260 return isdungeon(cur_dmap, Hero.current_screen);
884 }
885
886 92457 bool canPermSecret(int32_t dmap, int32_t screen)
887 {
888
2/2
✓ Branch 0 taken 13910 times.
✓ Branch 1 taken 78547 times.
92457 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
889 }
890
891 1263750992 int32_t MAPCOMBO(int32_t x, int32_t y)
892 {
893 1263750992 x = vbound(x, 0, world_w-1);
894 1263750992 y = vbound(y, 0, world_h-1);
895 1263750992 int pos = COMBOPOS(x%256, y%176);
896 1263750992 mapscr* scr = get_scr_for_world_xy(x, y);
897 1263750992 return scr->data[pos];
898 }
899
900 //specific layers 1 to 6
901 1488473328 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
902 {
903 DCHECK(layer >= 1 && layer <= 6);
904
3/4
✓ Branch 0 taken 1468569874 times.
✓ Branch 1 taken 19903454 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1468569874 times.
1488473328 if (!is_in_world_bounds(x, y) || layer <= 0)
905 19903454 return 0;
906
907 1468569874 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
908
2/2
✓ Branch 0 taken 472740182 times.
✓ Branch 1 taken 995829692 times.
1468569874 if (!m->is_valid())
909 995829692 return 0;
910
911 472740182 int pos = COMBOPOS(x%256, y%176);
912 472740182 return m->data[pos];
913 1488473328 }
914
915 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
916 {
917 DCHECK(layer >= 1 && layer <= 6);
918 if (!is_in_world_bounds(x, y) || layer <= 0)
919 return 0;
920
921 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
922 if (!m->is_valid())
923 return 0;
924
925 int pos = COMBOPOS(x%256, y%176);
926 return m->cset[pos];
927 }
928
929 372352 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
930 {
931 DCHECK(layer >= 1 && layer <= 6);
932
2/4
✓ Branch 0 taken 372352 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 372352 times.
372352 if (!is_in_world_bounds(x, y) || layer <= 0)
933 return 0;
934
935 372352 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
936
2/2
✓ Branch 0 taken 345286 times.
✓ Branch 1 taken 27066 times.
372352 if (!m->is_valid())
937 27066 return 0;
938
939 345286 int pos = COMBOPOS(x%256, y%176);
940 345286 return m->sflag[pos];
941 372352 }
942
943 40979 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
944 {
945 DCHECK(layer >= 1 && layer <= 6);
946
2/4
✓ Branch 0 taken 40979 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40979 times.
40979 if (!is_in_world_bounds(x, y) || layer <= 0)
947 return 0;
948
949 40979 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
950
2/2
✓ Branch 0 taken 40624 times.
✓ Branch 1 taken 355 times.
40979 if (!m->is_valid())
951 355 return 0;
952
953 40624 int pos = COMBOPOS(x%256, y%176);
954 40624 return combobuf[m->data[pos]].type;
955 40979 }
956
957 371064 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
958 {
959 DCHECK(layer >= 1 && layer <= 6);
960
2/4
✓ Branch 0 taken 371064 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 371064 times.
371064 if (!is_in_world_bounds(x, y) || layer <= 0)
961 return 0;
962
963 371064 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
964
2/2
✓ Branch 0 taken 343998 times.
✓ Branch 1 taken 27066 times.
371064 if (!m->is_valid())
965 27066 return 0;
966
967 343998 int pos = COMBOPOS(x%256, y%176);
968 343998 return combobuf[m->data[pos]].flag;
969 371064 }
970
971
972 // True if the FFC covers x, y and is not ethereal or a changer.
973 2675848580 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
974 {
975
2/2
✓ Branch 0 taken 750008244 times.
✓ Branch 1 taken 1925840336 times.
2675848580 if (ffc_handle.data()<=0)
976 750008244 return false;
977
978
2/2
✓ Branch 0 taken 314946537 times.
✓ Branch 1 taken 1610893799 times.
1925840336 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
979 314946537 return false;
980
981 1610893799 int32_t fx=ffc_handle.ffc->x.getInt();
982
4/4
✓ Branch 0 taken 1108805738 times.
✓ Branch 1 taken 502088061 times.
✓ Branch 2 taken 990415197 times.
✓ Branch 3 taken 118390541 times.
1610893799 if(x<fx || x>fx+(ffc_handle.scr->ffEffectWidth(ffc_handle.i)-1)) // FFC sizes are weird.
983 1492503258 return false;
984
985 118390541 int32_t fy=ffc_handle.ffc->y.getInt();
986
4/4
✓ Branch 0 taken 84638375 times.
✓ Branch 1 taken 33752166 times.
✓ Branch 2 taken 64688475 times.
✓ Branch 3 taken 19949900 times.
118390541 if(y<fy || y>fy+(ffc_handle.scr->ffEffectHeight(ffc_handle.i)-1))
987 98440641 return false;
988
989 19949900 return true;
990 2675848580 }
991
992 829767496 int32_t MAPFFCOMBO(int32_t x,int32_t y)
993 {
994
2/2
✓ Branch 0 taken 11864553 times.
✓ Branch 1 taken 817902943 times.
829767496 if (auto ffc_handle = getFFCAt(x, y))
995 11864553 return ffc_handle->data();
996 817902943 return 0;
997 829767496 }
998
999 207232 int32_t MAPCSET(int32_t x, int32_t y)
1000 {
1001
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
1002 return 0;
1003 207232 mapscr* scr = get_scr_for_world_xy(x, y);
1004 207232 int pos = COMBOPOS(x%256, y%176);
1005 207232 return scr->cset[pos];
1006 207232 }
1007
1008 87058293 int32_t MAPFLAG(int32_t x, int32_t y)
1009 {
1010
2/2
✓ Branch 0 taken 28507 times.
✓ Branch 1 taken 87029786 times.
87058293 if (!is_in_world_bounds(x, y))
1011 28507 return 0;
1012 87029786 mapscr* scr = get_scr_for_world_xy(x, y);
1013 87029786 int pos = COMBOPOS(x%256, y%176);
1014 87029786 return scr->sflag[pos];
1015 87058293 }
1016
1017 95535040 int32_t COMBOTYPE(int32_t x,int32_t y)
1018 {
1019 95535040 int32_t b=1;
1020
2/2
✓ Branch 0 taken 64699716 times.
✓ Branch 1 taken 30835324 times.
95535040 if(x&8) b<<=2;
1021
2/2
✓ Branch 0 taken 60202941 times.
✓ Branch 1 taken 35332099 times.
95535040 if(y&8) b<<=1;
1022
1023
2/2
✓ Branch 0 taken 191062333 times.
✓ Branch 1 taken 95519803 times.
286582136 for (int32_t i = 0; i <= 1; ++i)
1024 {
1025
2/2
✓ Branch 0 taken 158746666 times.
✓ Branch 1 taken 32315667 times.
191062333 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1026 {
1027
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 158746666 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
158746666 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1028 158746666 }
1029 else
1030 {
1031
4/4
✓ Branch 0 taken 18389 times.
✓ Branch 1 taken 32297278 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 15237 times.
32315667 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1032 }
1033 191047096 }
1034
1035 95519803 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1036
5/6
✓ Branch 0 taken 3536077 times.
✓ Branch 1 taken 91983726 times.
✓ Branch 2 taken 1909096 times.
✓ Branch 3 taken 1626981 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1909096 times.
95519803 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1037 {
1038
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909096 times.
1909096 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1039
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909096 times.
1909096 if(cmb.usrflags&cflag3) return cNONE;
1040 1909096 }
1041 95519803 return cmb.type;
1042 95535040 }
1043
1044 59029490 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1045 {
1046 59029490 return combobuf[MAPFFCOMBO(x,y)].type;
1047 }
1048
1049 7144117 int32_t FFORCOMBO(int32_t x, int32_t y)
1050 {
1051
2/2
✓ Branch 0 taken 78428 times.
✓ Branch 1 taken 7065689 times.
7144117 if (auto ffc_handle = getFFCAt(x, y))
1052 78428 return ffc_handle->data();
1053
1054 7065689 return MAPCOMBO(x,y);
1055 7144117 }
1056
1057 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1058 {
1059 for (int32_t i = 0; i <= 1; ++i)
1060 {
1061 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1062 {
1063 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1064 }
1065 else
1066 {
1067 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1068 }
1069 }
1070 int32_t b=1;
1071
1072 if(x&8) b<<=2;
1073
1074 if(y&8) b<<=1;
1075 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1076 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1077 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1078 return cmb.type;
1079 }
1080
1081 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1082 {
1083 if (auto ffc_handle = getFFCAt(x, y))
1084 return ffc_handle->data();
1085
1086 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1087 }
1088
1089 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1090 {
1091 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1092 }
1093
1094 83411087 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1095 {
1096
2/2
✓ Branch 0 taken 28219 times.
✓ Branch 1 taken 83382868 times.
83411087 if (!is_in_world_bounds(x, y))
1097 28219 return 0;
1098
1099 83382868 mapscr* scr = get_scr_for_world_xy(x, y);
1100 83382868 int pos = COMBOPOS(x%256, y%176);
1101 83382868 return combobuf[scr->data[pos]].flag;
1102 83411087 }
1103
1104 68111964 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1105 {
1106
2/2
✓ Branch 0 taken 777663 times.
✓ Branch 1 taken 67334301 times.
68111964 if (auto ffc_handle = getFFCAt(x, y))
1107 777663 return ffc_handle->cflag();
1108
1109 67334301 return 0;
1110 68111964 }
1111
1112 1237661380 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1113 {
1114 2784623915 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1115 1546962535 return ffcIsAt(ffc_handle, x, y);
1116 });
1117 }
1118
1119 3051 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1120 {
1121
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3051 times.
3051 if (!rpos_handle.scr->is_valid()) return 0;
1122 3051 return rpos_handle.data();
1123 3051 }
1124
1125 3017417449 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1126 {
1127 DCHECK_LAYER_NEG1_INDEX(layer);
1128
2/2
✓ Branch 0 taken 22065451 times.
✓ Branch 1 taken 2995351998 times.
3017417449 if (!is_in_world_bounds(x, y)) return 0;
1129
2/2
✓ Branch 0 taken 2896221883 times.
✓ Branch 1 taken 99130115 times.
2995351998 if (layer == -1) return MAPCOMBO(x, y);
1130
1131 2896221883 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1132
2/2
✓ Branch 0 taken 1795795697 times.
✓ Branch 1 taken 1100426186 times.
2896221883 if (!rpos_handle.scr->is_valid()) return 0;
1133
1134 1100426186 return rpos_handle.data();
1135 3017417449 }
1136
1137 19160534 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1138 {
1139 19160534 auto cid = handle.data();
1140 19160534 auto* cmb = &handle.combo();
1141 19160534 bool done = false;
1142 19160534 std::set<int32_t> visited;
1143
2/2
✓ Branch 0 taken 19160534 times.
✓ Branch 1 taken 19160534 times.
38321068 while(!done)
1144 {
1145
2/4
✓ Branch 0 taken 19160534 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19160534 times.
19160534 if(visited.contains(cid))
1146 {
1147 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1148 break; // prevent infinite loop
1149 }
1150
1/2
✓ Branch 0 taken 19160534 times.
✗ Branch 1 not taken.
19160534 visited.insert(cid);
1151
1152 19160534 done = true; // don't loop again unless something changes
1153
1/2
✓ Branch 0 taken 19160534 times.
✗ Branch 1 not taken.
20044677 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
1154 884143 return trig.trigger_flags.get(TRIGFLAG_SCREENLOAD);
1155 });
1156
2/4
✓ Branch 0 taken 19160534 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 19160534 times.
19160534 if(handle.data() != cid)
1157 {
1158 cid = handle.data();
1159 cmb = &handle.combo();
1160 done = false; // loop again for the new combo
1161 }
1162 }
1163 19160534 }
1164 52904 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1165 {
1166 52904 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1167 52904 }
1168 36494 void handle_region_load_trigger()
1169 {
1170
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 36342 times.
36494 if (is_in_scrolling_region())
1171 {
1172
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1173 {
1174
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1175 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1176 19456 }
1177 152 }
1178 36342 else handle_screen_load_trigger(create_screen_handles_one(get_scr(Hero.current_screen)));
1179 36494 }
1180
1181 15262 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1182 {
1183 15262 auto screen_handles = create_screen_handles_one(&scr);
1184
1185
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 14723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15262 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1186 {
1187 539 reveal_hidden_stairs(&scr, screen, false);
1188 539 bool do_layers = false;
1189 539 bool from_active_screen = false;
1190 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1191 539 }
1192
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if (flags & mLIGHTBEAM)
1193 {
1194 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1195 if (rpos_handle.ctype() == cLIGHTTARGET)
1196 {
1197 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1198 rpos_handle.increment_data();
1199 }
1200 });
1201 }
1202
1203 15262 int lvl = DMaps[cur_dmap].level;
1204 15262 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1205 15262 toggle_gswitches_load(screen_handles);
1206
1207
2/2
✓ Branch 0 taken 15170 times.
✓ Branch 1 taken 92 times.
15262 if(flags&mLOCKBLOCK) // if special stuff done before
1208 {
1209 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1210 92 }
1211
1212
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1213 {
1214 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1215 }
1216
1217
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1218 {
1219 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1220 }
1221
1222
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mCHEST) // if special stuff done before
1223 {
1224 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1225 }
1226
1227
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 if(flags&mBOSSCHEST) // if special stuff done before
1228 {
1229 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1230 }
1231
1232
1233 15262 int mi = mapind(map, screen);
1234 15262 clear_xdoors_mi(screen_handles, mi);
1235 15262 clear_xstatecombos_mi(screen_handles, mi);
1236
1237 15262 handle_screen_load_trigger(screen_handles);
1238 15262 }
1239
1240 40981 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1241 {
1242
2/4
✓ Branch 0 taken 40981 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40981 times.
40981 if (map < 0 || screen < 0)
1243 return std::nullopt;
1244
1245 40981 const mapscr* source = get_canonical_scr(map, screen);
1246
2/2
✓ Branch 0 taken 39256 times.
✓ Branch 1 taken 1725 times.
40981 if (!source->is_valid())
1247 1725 return std::nullopt;
1248
1249
2/2
✓ Branch 0 taken 7936 times.
✓ Branch 1 taken 31320 times.
39256 if (layer >= 0)
1250 {
1251
2/2
✓ Branch 0 taken 23994 times.
✓ Branch 1 taken 7326 times.
31320 if (source->layermap[layer] <= 0)
1252 23994 return std::nullopt;
1253
1254 7326 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1255
1/2
✓ Branch 0 taken 7326 times.
✗ Branch 1 not taken.
7326 if (!source->is_valid())
1256 return std::nullopt;
1257 7326 }
1258
1259
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1260 15262 mapscr scr = *source;
1261
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1262
1263
1/2
✓ Branch 0 taken 15262 times.
✗ Branch 1 not taken.
15262 return scr;
1264 40981 }
1265
1266 14990 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1267 {
1268
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if (map < 0 || screen < 0) return 0;
1269
1270
2/4
✓ Branch 0 taken 14990 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14990 times.
14990 if(pos>175 || pos < 0)
1271 return 0;
1272
1273 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1274 // `apply_state_changes_to_screen` checks).
1275
4/5
✓ Branch 0 taken 4736 times.
✓ Branch 1 taken 10254 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4736 times.
✓ Branch 4 taken 10254 times.
19726 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1276 4736 return s->data[pos];
1277
1278 10254 return 0;
1279 14990 }
1280
1281 // Read from the current temporary screens or, if (map, screen) is not loaded,
1282 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1283 251212406 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1284 {
1285 DCHECK_LAYER_NEG1_INDEX(layer);
1286 DCHECK(map >= 0 && screen >= 0);
1287
1288
2/2
✓ Branch 0 taken 251197416 times.
✓ Branch 1 taken 14990 times.
251212406 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1289
1290 // Screen is not in the current region, so we have to load and trigger some secrets.
1291 14990 int pos = COMBOPOS(x, y);
1292 14990 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1293 251212406 }
1294
1295 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1296 {
1297 DCHECK_LAYER_NEG1_INDEX(layer);
1298 DCHECK(map >= 0 && screen >= 0);
1299 DCHECK(is_valid_rpos(rpos));
1300
1301 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1302
1303 // Screen is not currently loaded, so we have to load and trigger some secrets.
1304 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1305 }
1306
1307 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1308 {
1309 DCHECK_LAYER_NEG1_INDEX(layer);
1310 if (!is_in_world_bounds(x, y))
1311 return 0;
1312 if (layer == -1) return MAPCSET(x, y);
1313
1314 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1315 if (!rpos_handle.scr->is_valid()) return 0;
1316
1317 return rpos_handle.cset();
1318 }
1319
1320 102412209 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1321 {
1322 DCHECK_LAYER_NEG1_INDEX(layer);
1323
3/4
✓ Branch 0 taken 5385623 times.
✓ Branch 1 taken 97026586 times.
✓ Branch 2 taken 5385623 times.
✗ Branch 3 not taken.
102412209 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1324 return 0;
1325
2/2
✓ Branch 0 taken 84274547 times.
✓ Branch 1 taken 18137662 times.
102412209 if (layer == -1) return MAPFLAG(x, y);
1326
1327 84274547 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1328
2/2
✓ Branch 0 taken 63730019 times.
✓ Branch 1 taken 20544528 times.
84274547 if (!rpos_handle.scr->is_valid()) return 0;
1329
1330 20544528 return rpos_handle.sflag();
1331 102412209 }
1332
1333 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1334 {
1335 if(layer < 1)
1336 {
1337 for (int32_t i = layer+1; i <= 1; ++i)
1338 {
1339 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1340 {
1341 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1342 }
1343 else
1344 {
1345 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1346 }
1347 }
1348 }
1349 if(layer==-1) return COMBOTYPE(x,y);
1350
1351 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1352 if (!rpos_handle.scr->is_valid()) return 0;
1353
1354 return rpos_handle.ctype();
1355 }
1356
1357 // Returns the flag for the combo at the given position.
1358 // This is also known as an "inherent flag".
1359 100578885 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1360 {
1361 DCHECK_LAYER_NEG1_INDEX(layer);
1362
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 100578597 times.
100578885 if (!is_in_world_bounds(x, y))
1363 288 return 0;
1364
2/2
✓ Branch 0 taken 84177975 times.
✓ Branch 1 taken 16400622 times.
100578597 if (layer == -1) return MAPCOMBOFLAG(x, y);
1365
1366 84177975 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1367
2/2
✓ Branch 0 taken 63748345 times.
✓ Branch 1 taken 20429630 times.
84177975 if (!rpos_handle.scr->is_valid()) return 0;
1368
1369 20429630 return rpos_handle.cflag();
1370 100578885 }
1371
1372 11686167 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1373 {
1374 DCHECK_LAYER_ZERO_INDEX(layer);
1375 11686167 auto rpos_handle = get_rpos_handle(rpos, layer);
1376
2/2
✓ Branch 0 taken 4465414 times.
✓ Branch 1 taken 7220753 times.
11686167 if (!rpos_handle.scr->is_valid()) return false;
1377
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 7216188 times.
7220753 if (rpos_handle.sflag() == flag) return true;
1378
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 7178483 times.
7216188 if (rpos_handle.cflag() == flag) return true;
1379 7178483 return false;
1380 11686167 }
1381
1382 1705537 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1383 {
1384 DCHECK(is_valid_rpos(rpos));
1385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1705537 times.
1705537 if (rpos > region_max_rpos) return false;
1386
1387
2/2
✓ Branch 0 taken 11686167 times.
✓ Branch 1 taken 1663267 times.
13349434 for(auto q = 0; q < 7; ++q)
1388 {
1389
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11643897 times.
11686167 if(HASFLAG(flag, q, rpos))
1390 42270 return true;
1391 11643897 }
1392 1663267 return false;
1393 1705537 }
1394
1395 const char *screenstate_string[32] =
1396 {
1397 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "Some Enemies Never Return",
1398 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1399 "Boss Locked Chests", "Secrets", "Visited", "Light Beams",
1400 "All Enemies Don't Return", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1401 "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1402 };
1403
1404 36562 void eventlog_mapflags()
1405 {
1406 36562 std::ostringstream oss;
1407
1408 36562 int mi = mapind(cur_map, home_screen);
1409
1/2
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
36562 dword g = game->maps[mi];
1410
1411
2/4
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36562 times.
✗ Branch 3 not taken.
36562 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1412
2/2
✓ Branch 0 taken 15710 times.
✓ Branch 1 taken 20852 times.
36562 if(g) // Main States
1413 {
1414 static const int order[] =
1415 {
1416 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1417 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1418 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1419 mNEVERRET, mTMPNORET, mLIGHTBEAM, mNO_ENEMIES_RETURN
1420 };
1421
1422
1/2
✓ Branch 0 taken 15710 times.
✗ Branch 1 not taken.
15710 oss << " [";
1423 15710 bool comma = false;
1424
2/2
✓ Branch 0 taken 15710 times.
✓ Branch 1 taken 251360 times.
267070 for(int fl : order)
1425 {
1426
2/2
✓ Branch 0 taken 9640 times.
✓ Branch 1 taken 241720 times.
251360 if(!(g&fl))
1427 241720 continue;
1428 9640 byte ind = byte(log2(double(fl)));
1429
2/2
✓ Branch 0 taken 2072 times.
✓ Branch 1 taken 7568 times.
9640 if(comma)
1430
1/2
✓ Branch 0 taken 2072 times.
✗ Branch 1 not taken.
2072 oss << ", ";
1431
1/2
✓ Branch 0 taken 9640 times.
✗ Branch 1 not taken.
9640 oss << screenstate_string[ind];
1432 9640 comma = true;
1433 }
1434
1/2
✓ Branch 0 taken 15710 times.
✗ Branch 1 not taken.
15710 oss << "]";
1435 15710 }
1436
3/4
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 36506 times.
36562 if(game->xstates[mi]) // ExStates
1437 {
1438
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 oss << " Ex[";
1439 56 bool comma = false;
1440
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 1792 times.
1848 for(byte fl = 0; fl < 32; ++fl)
1441 {
1442
3/4
✓ Branch 0 taken 1792 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 77 times.
✓ Branch 3 taken 1715 times.
1792 if(game->xstates[mi] & (1<<fl))
1443 {
1444
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 56 times.
77 if(comma)
1445
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 oss << ", ";
1446
1/2
✓ Branch 0 taken 77 times.
✗ Branch 1 not taken.
77 oss << int(fl);
1447 77 comma = true;
1448 77 }
1449 1792 }
1450
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 oss << "]";
1451 56 }
1452 { // ExDoors
1453
2/2
✓ Branch 0 taken 36562 times.
✓ Branch 1 taken 146248 times.
182810 for(int q = 0; q < 4; ++q)
1454 {
1455 146248 bool comma = false;
1456
3/4
✓ Branch 0 taken 146248 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 146246 times.
✓ Branch 3 taken 2 times.
146248 if(auto v = game->xdoors[mi][q])
1457 {
1458
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(comma)
1459 oss << ",";
1460
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else oss << " ExDoor";
1461
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 oss << "[" << dirstr[q];
1462
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 for(int fl = 0; fl < 8; ++fl)
1463
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
19 if(v & (1<<fl))
1464
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 oss << " " << int(fl);
1465
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 oss << "]";
1466 2 comma = true;
1467 2 }
1468 146248 }
1469 }
1470
2/4
✓ Branch 0 taken 36562 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 36562 times.
36562 Z_eventlog("%s\n", oss.str().c_str());
1471 36562 }
1472
1473 // set specific flag
1474 5932 void setmapflag(mapscr* scr, uint32_t flag)
1475 {
1476
2/2
✓ Branch 0 taken 5919 times.
✓ Branch 1 taken 13 times.
5932 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1477 5932 int mi = mapind(cur_map, scr->screen);
1478 5932 setmapflag_mi(scr, mi, flag);
1479 5932 }
1480 57 void setmapflag_homescr(uint32_t flag)
1481 {
1482 57 int mi = mapind(cur_map, home_screen);
1483 57 setmapflag_mi(origin_scr, mi, flag);
1484 57 }
1485 2065 void setmapflag_mi(int32_t mi, uint32_t flag)
1486 {
1487 2065 byte cscr = mi&((1<<7)-1);
1488 2065 byte cmap = (mi>>7);
1489 2065 mapscr* scr = origin_scr;
1490
2/2
✓ Branch 0 taken 835 times.
✓ Branch 1 taken 1230 times.
2065 if (is_in_current_region(cmap, cscr))
1491 1230 scr = get_scr(cmap, cscr);
1492
1493 2065 setmapflag_mi(scr, mi, flag);
1494 2065 }
1495
1496 8877 static void log_state_change(int map, int screen, std::string action)
1497 {
1498
6/6
✓ Branch 0 taken 1937 times.
✓ Branch 1 taken 6940 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 941 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 644 times.
8877 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1499 7292 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1500 else
1501 1585 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1502 8877 }
1503
1504 8054 void setmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag)
1505 {
1506 8054 byte cscr = mi&((1<<7)-1);
1507 8054 byte cmap = (mi>>7);
1508
1509 8054 double temp=log2((double)flag);
1510
1/2
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
8054 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1511 8054 const char* replay_state_string = state_string;
1512
2/2
✓ Branch 0 taken 7534 times.
✓ Branch 1 taken 520 times.
8054 if(temp == 6) replay_state_string = "No Return";
1513
1514
3/4
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1596 times.
✓ Branch 3 taken 6458 times.
8054 if (replay_is_active() && !(game->maps[mi] & flag))
1515
1/2
✓ Branch 0 taken 6458 times.
✗ Branch 1 not taken.
6458 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, replay_state_string));
1516 8054 game->maps[mi] |= flag;
1517
1/2
✓ Branch 0 taken 8054 times.
✗ Branch 1 not taken.
8054 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1518
1519
2/2
✓ Branch 0 taken 2518 times.
✓ Branch 1 taken 5536 times.
8054 if((scr->nocarry&flag)!=flag)
1520 {
1521 5536 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1522 5536 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1523
1524 5536 std::vector<int32_t> done;
1525
2/2
✓ Branch 0 taken 5423 times.
✓ Branch 1 taken 113 times.
5536 bool looped = (nmap==cmap+1 && nscr==cscr);
1526
1527
6/6
✓ Branch 0 taken 458 times.
✓ Branch 1 taken 5485 times.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 407 times.
✓ Branch 4 taken 407 times.
✓ Branch 5 taken 5536 times.
5943 while((nmap!=0) && !looped && !(nscr>=128))
1528 {
1529
3/4
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 191 times.
✓ Branch 3 taken 216 times.
407 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1530 {
1531
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 log_state_change(nmap, nscr, "State change carried over");
1532
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 if (replay_is_active())
1533
2/4
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
216 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, replay_state_string));
1534
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 game->maps[((nmap-1)<<7)+nscr] |= flag;
1535 216 }
1536
1537 407 cmap=nmap;
1538 407 cscr=nscr;
1539 407 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1540 407 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1541
1542
2/2
✓ Branch 0 taken 916 times.
✓ Branch 1 taken 407 times.
1323 for(auto it = done.begin(); it != done.end(); it++)
1543 {
1544
2/2
✓ Branch 0 taken 865 times.
✓ Branch 1 taken 51 times.
916 if(*it == ((nmap-1)<<7)+nscr)
1545 51 looped = true;
1546 916 }
1547
1548
1/2
✓ Branch 0 taken 407 times.
✗ Branch 1 not taken.
407 done.push_back(((nmap-1)<<7)+nscr);
1549 }
1550 5536 }
1551 8054 }
1552
1553 void unsetmapflag_home(uint32_t flag, bool anyflag)
1554 {
1555 int mi = mapind(cur_map, home_screen);
1556 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1557 }
1558
1559 void unsetmapflag(mapscr* scr, uint32_t flag, bool anyflag)
1560 {
1561 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1562 int mi = mapind(cur_map, scr->screen);
1563 unsetmapflag_mi(scr, mi, flag, anyflag);
1564 }
1565
1566 471 void unsetmapflag_mi(int32_t mi, uint32_t flag, bool anyflag)
1567 {
1568 471 byte cscr = mi&((1<<7)-1);
1569 471 byte cmap = (mi>>7);
1570 471 mapscr* scr = origin_scr;
1571
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1572 11 scr = get_scr(cmap, cscr);
1573
1574 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1575 471 }
1576
1577 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag, bool anyflag)
1578 {
1579 471 byte cscr = mi&((1<<7)-1);
1580 471 byte cmap = (mi>>7);
1581
1582
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1583 460 game->maps[mi] &= ~flag;
1584
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1585 {
1586 if(!(scr->flags4&fNOITEMRESET))
1587 game->maps[mi] &= ~flag;
1588 }
1589 11 else game->maps[mi] &= ~flag;
1590
1591 471 double temp=log2((double)flag);
1592
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1593
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1594
1595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 471 times.
471 if((scr->nocarry&flag)!=flag)
1596 {
1597 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1598 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1599
1600 471 std::vector<int32_t> done;
1601
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1602
1603
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1604 {
1605
3/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 72 times.
84 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1606 {
1607
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1608
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1609 72 }
1610
1611 84 cmap=nmap;
1612 84 cscr=nscr;
1613 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1614 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1615
1616
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 546 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1617 {
1618
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1619 6 looped = true;
1620 546 }
1621
1622
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1623 }
1624 471 }
1625 471 }
1626
1627 51927401 bool getmapflag(int32_t screen, uint32_t flag)
1628 {
1629
2/2
✓ Branch 0 taken 1345925 times.
✓ Branch 1 taken 50581476 times.
51927401 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1630 51927401 return (game->maps[mi] & flag) != 0;
1631 }
1632 6408611 bool getmapflag(mapscr* scr, uint32_t flag)
1633 {
1634 6408611 return getmapflag(scr->screen, flag);
1635 }
1636
1637 57 void setxmapflag(int32_t screen, uint32_t flag)
1638 {
1639
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1640 57 setxmapflag_mi(mi, flag);
1641 57 }
1642 59 void setxmapflag_mi(int32_t mi, uint32_t flag)
1643 {
1644
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if(game->xstates[mi] & flag) return;
1645 59 byte cscr = mi&((1<<7)-1);
1646 59 byte cmap = (mi>>7);
1647
1648 59 byte temp=(byte)log2((double)flag);
1649
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1650
1651 59 game->xstates[mi] |= flag;
1652
1653 59 mapscr* scr = origin_scr;
1654
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 59 times.
59 if (is_in_current_region(cmap, cscr))
1655 59 scr = get_scr(cmap, cscr);
1656
1657
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
59 if((scr->exstate_carry&flag)==flag)
1658 {
1659 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1660 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1661
1662 std::vector<int32_t> done;
1663 bool looped = (nmap==cmap+1 && nscr==cscr);
1664
1665 while((nmap!=0) && !looped && !(nscr>=128))
1666 {
1667 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1668 {
1669 log_state_change(nmap, nscr, "ExState change carried over");
1670 if (replay_is_active())
1671 replay_step_comment(fmt::format("map {} scr {} exstate {} carry", nmap, nscr, temp));
1672 game->xstates[((nmap-1)<<7)+nscr] |= flag;
1673 }
1674
1675 cmap=nmap;
1676 cscr=nscr;
1677 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1678 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1679
1680 for(auto it = done.begin(); it != done.end(); it++)
1681 {
1682 if(*it == ((nmap-1)<<7)+nscr)
1683 looped = true;
1684 }
1685
1686 done.push_back(((nmap-1)<<7)+nscr);
1687 }
1688 }
1689 59 }
1690 2 void unsetxmapflag(int32_t screen, uint32_t flag)
1691 {
1692
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1693 2 unsetxmapflag_mi(mi, flag);
1694 2 }
1695 2 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1696 {
1697
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!(game->xstates[mi] & flag)) return;
1698 1 byte cscr = mi&((1<<7)-1);
1699 1 byte cmap = (mi>>7);
1700 1 byte temp=(byte)log2((double)flag);
1701
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1702 1 game->xstates[mi] &= ~flag;
1703
1704 1 mapscr* scr = origin_scr;
1705
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (is_in_current_region(cmap, cscr))
1706 1 scr = get_scr(cmap, cscr);
1707
1708
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((scr->exstate_carry&flag)==flag)
1709 {
1710 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1711 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1712
1713 std::vector<int32_t> done;
1714 bool looped = (nmap==cmap+1 && nscr==cscr);
1715
1716 while((nmap!=0) && !looped && !(nscr>=128))
1717 {
1718 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1719 {
1720 log_state_change(nmap, nscr, "ExState change carried over");
1721 game->xstates[((nmap-1)<<7)+nscr] &= ~flag;
1722 }
1723
1724 cmap=nmap;
1725 cscr=nscr;
1726 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1727 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1728
1729 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1730 {
1731 if(*it == ((nmap-1)<<7)+nscr)
1732 looped = true;
1733 }
1734
1735 done.push_back(((nmap-1)<<7)+nscr);
1736 }
1737 }
1738 2 }
1739 82 bool getxmapflag(int32_t screen, uint32_t flag)
1740 {
1741
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 82 times.
82 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1742 82 return getxmapflag_mi(mi, flag);
1743 }
1744 488350944 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1745 {
1746 488350944 return (game->xstates[mi] & flag) != 0;
1747 }
1748
1749 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1750 {
1751
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1752 return;
1753
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1754 return;
1755
1756
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1757
1758 4 int cscr = mi % MAPSCRSNORMAL;
1759 4 int cmap = mi / MAPSCRSNORMAL;
1760
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1761
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1762 else
1763 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1764 4 }
1765 488350857 bool getxdoor_mi(uint mi, uint dir, uint ind)
1766 {
1767
3/6
✓ Branch 0 taken 488350857 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 488350857 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 488350857 times.
488350857 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1768 return false;
1769 488350857 return (game->xdoors[mi][dir] & (1<<ind));
1770 488350857 }
1771 9 bool getxdoor(int32_t screen, uint dir, uint ind)
1772 {
1773 9 int mi = mapind(cur_map, screen);
1774 9 return getxdoor_mi(mi,dir,ind);
1775 }
1776
1777 401 void set_doorstate_mi(uint mi, uint dir)
1778 {
1779
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1780 return;
1781 401 setmapflag_mi(mi, mDOOR_UP << dir);
1782
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1783 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1784 401 }
1785 401 void set_doorstate(uint screen, uint dir)
1786 {
1787 401 int mi = mapind(cur_map, screen);
1788 401 set_doorstate_mi(mi, dir);
1789 401 }
1790
1791 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1792 {
1793
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1794 return;
1795 2 setxdoor_mi(mi, dir, ind, state);
1796
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1797 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1798 2 }
1799
1800 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1801 {
1802 2 int mi = mapind(cur_map, screen);
1803 2 set_xdoorstate_mi(mi, dir, ind, state);
1804 2 }
1805
1806 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1807 // returns: -1 = not a warp screen
1808 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1809 {
1810 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1811
1812
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1813 return -1;
1814
1815 57 int32_t ring=scr->catchall;
1816 57 int32_t size=QMisc.warp[ring].size;
1817
1818
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1819 return -2;
1820
1821 57 int32_t index=-1;
1822
1823
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1824
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1825 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1826 57 index=i;
1827
1828
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1829 return -3;
1830
1831 57 index = (index+dw)%size;
1832 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1833 57 }
1834
1835 15355138 void update_combo_cycling()
1836 {
1837 15355138 auto& combo_cache = combo_caches::can_cycle;
1838
1839 static int32_t newdata[176];
1840 static int32_t newcset[176];
1841 static bool initialized=false;
1842
1843 // Just a simple bit of optimization
1844
2/2
✓ Branch 0 taken 15354819 times.
✓ Branch 1 taken 319 times.
15355138 if(!initialized)
1845 {
1846
2/2
✓ Branch 0 taken 56144 times.
✓ Branch 1 taken 319 times.
56463 for(int32_t i=0; i<176; i++)
1847 {
1848 56144 newdata[i]=-1;
1849 56144 newcset[i]=-1;
1850 56144 }
1851
1852 319 initialized=true;
1853 319 }
1854
1855 15355138 std::set<uint16_t> restartanim;
1856
1857
1/2
✓ Branch 0 taken 15355138 times.
✗ Branch 1 not taken.
31099644 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1858 15744506 int screen = scr->screen;
1859 int32_t x;
1860
1861
2/2
✓ Branch 0 taken 2771033056 times.
✓ Branch 1 taken 15744506 times.
2786777562 for(int32_t i=0; i<176; i++)
1862 {
1863 2771033056 x=scr->data[i];
1864 2771033056 auto& mini_cmb = combo_cache.minis[x];
1865
2/2
✓ Branch 0 taken 3282224 times.
✓ Branch 1 taken 2767750832 times.
2771033056 if (!mini_cmb.can_cycle)
1866 2767750832 continue;
1867
1868 3282224 newcombo const& cmb = combobuf[x];
1869
1870 //time to restart
1871
4/4
✓ Branch 0 taken 904477 times.
✓ Branch 1 taken 2377747 times.
✓ Branch 2 taken 475770 times.
✓ Branch 3 taken 428707 times.
3282224 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1872 {
1873 428707 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1874
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428707 times.
428707 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1875 428707 newdata[i] = c;
1876
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428687 times.
428707 if(!(cmb.animflags & AF_CYCLENOCSET))
1877
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428687 times.
428687 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1878
1879
2/2
✓ Branch 0 taken 427663 times.
✓ Branch 1 taken 1044 times.
428707 if(combobuf[c].animflags & AF_CYCLE)
1880 {
1881 1044 restartanim.insert(c);
1882 1044 }
1883 428707 }
1884 3282224 }
1885
1886 15744506 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1887
2/2
✓ Branch 0 taken 2771033056 times.
✓ Branch 1 taken 15744506 times.
2786777562 for(int32_t i=0; i<176; i++)
1888 {
1889
2/2
✓ Branch 0 taken 428707 times.
✓ Branch 1 taken 2770604349 times.
2771033056 if(newdata[i]==-1)
1890 2770604349 continue;
1891
1892 428707 rpos_t rpos = (rpos_t)(rpos_base + i);
1893 428707 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1894 428707 screen_combo_modify_preroutine(rpos_handle);
1895 428707 scr->data[i]=newdata[i];
1896
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428687 times.
428707 if(newcset[i]>-1)
1897 428687 scr->cset[i]=newcset[i];
1898 428707 screen_combo_modify_postroutine(rpos_handle);
1899
1900 428707 newdata[i]=-1;
1901 428707 newcset[i]=-1;
1902 428707 }
1903
1904 15744506 word c = scr->numFFC();
1905
2/2
✓ Branch 0 taken 15744506 times.
✓ Branch 1 taken 454715631 times.
470460137 for(word i=0; i<c; i++)
1906 {
1907 454715631 ffcdata& ffc = scr->ffcs[i];
1908 454715631 auto& mini_cmb = combo_cache.minis[ffc.data];
1909
2/2
✓ Branch 0 taken 7727 times.
✓ Branch 1 taken 454707904 times.
454715631 if (!mini_cmb.can_cycle)
1910 454707904 continue;
1911
1912 7727 newcombo const& cmb = combobuf[ffc.data];
1913
1914 //time to restart
1915
4/4
✓ Branch 0 taken 1181 times.
✓ Branch 1 taken 6546 times.
✓ Branch 2 taken 856 times.
✓ Branch 3 taken 325 times.
7727 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1916 {
1917 325 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1918
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 325 times.
325 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1919 325 zc_ffc_set(ffc, c);
1920
2/2
✓ Branch 0 taken 217 times.
✓ Branch 1 taken 108 times.
325 if(!(cmb.animflags & AF_CYCLENOCSET))
1921
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1922
1923
2/2
✓ Branch 0 taken 265 times.
✓ Branch 1 taken 60 times.
325 if(combobuf[ffc.data].animflags & AF_CYCLE)
1924 {
1925 60 restartanim.insert(ffc.data);
1926 60 }
1927 325 }
1928 7727 }
1929
1930
2/2
✓ Branch 0 taken 8418399 times.
✓ Branch 1 taken 7326107 times.
15744506 if(get_qr(qr_CMBCYCLELAYERS))
1931 {
1932
2/2
✓ Branch 0 taken 43956642 times.
✓ Branch 1 taken 7326107 times.
51282749 for(int32_t j=1; j<=6; j++)
1933 {
1934 43956642 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1935
2/2
✓ Branch 0 taken 13893876 times.
✓ Branch 1 taken 30062766 times.
43956642 if (!layer_scr)
1936 30062766 continue;
1937
1938
2/2
✓ Branch 0 taken 2445322176 times.
✓ Branch 1 taken 13893876 times.
2459216052 for(int32_t i=0; i<176; i++)
1939 {
1940 2445322176 x=layer_scr->data[i];
1941 2445322176 auto& mini_cmb = combo_cache.minis[x];
1942
2/2
✓ Branch 0 taken 2424344 times.
✓ Branch 1 taken 2442897832 times.
2445322176 if (!mini_cmb.can_cycle)
1943 2442897832 continue;
1944
1945 2424344 newcombo const& cmb = combobuf[x];
1946
1947 //time to restart
1948
4/4
✓ Branch 0 taken 67298 times.
✓ Branch 1 taken 2357046 times.
✓ Branch 2 taken 50626 times.
✓ Branch 3 taken 16672 times.
2424344 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1949 {
1950 16672 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1951
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16672 times.
16672 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1952 16672 newdata[i] = c;
1953
2/2
✓ Branch 0 taken 644 times.
✓ Branch 1 taken 16028 times.
16672 if(!(cmb.animflags & AF_CYCLENOCSET))
1954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16028 times.
16028 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1955 644 else newcset[i] = layer_scr->cset[i];
1956
1957
2/2
✓ Branch 0 taken 6689 times.
✓ Branch 1 taken 9983 times.
16672 if(combobuf[c].animflags & AF_CYCLE)
1958 {
1959 9983 restartanim.insert(c);
1960 9983 }
1961 16672 }
1962 2424344 }
1963
1964
2/2
✓ Branch 0 taken 2445322176 times.
✓ Branch 1 taken 13893876 times.
2459216052 for (int32_t i=0; i<176; i++)
1965 {
1966
2/2
✓ Branch 0 taken 2445305504 times.
✓ Branch 1 taken 16672 times.
2445322176 if(newdata[i]!=-1)
1967 {
1968 16672 layer_scr->data[i]=newdata[i];
1969
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16672 times.
16672 if(newcset[i]>-1)
1970 16672 layer_scr->cset[i]=newcset[i];
1971 16672 newdata[i]=-1;
1972 16672 newcset[i]=-1;
1973 16672 }
1974 2445322176 }
1975 13893876 }
1976 7326107 }
1977 15744506 });
1978
1979
2/2
✓ Branch 0 taken 15355138 times.
✓ Branch 1 taken 2661 times.
15357799 for (auto i : restartanim)
1980 {
1981 2661 combobuf[i].tile = combobuf[i].o_tile;
1982 2661 combobuf[i].cur_frame=0;
1983 2661 combobuf[i].aclk = 0;
1984
1/2
✓ Branch 0 taken 2661 times.
✗ Branch 1 not taken.
2661 combo_caches::drawing.refresh(i);
1985 }
1986 15355138 }
1987
1988 1425841265 bool iswater_type(int32_t type)
1989 {
1990 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
1991 1425841265 return (combo_class_buf[type].water!=0);
1992 }
1993
1994 bool iswater(int32_t combo)
1995 {
1996 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
1997 }
1998 5280776 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
1999 {
2000 5280776 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
2001 }
2002
2003 // (x, y) are world coordinates
2004 68216255 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
2005 {
2006
8/8
✓ Branch 0 taken 68168392 times.
✓ Branch 1 taken 47863 times.
✓ Branch 2 taken 68126532 times.
✓ Branch 3 taken 41860 times.
✓ Branch 4 taken 68057049 times.
✓ Branch 5 taken 69483 times.
✓ Branch 6 taken 63405 times.
✓ Branch 7 taken 67993644 times.
68216255 if (x<0 || x>=world_w || y<0 || y>=world_h)
2007 222611 return false;
2008
2009 67993644 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
2010 68216255 }
2011
2012 148604330 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
2013 {
2014 DCHECK_LAYER_NEG1_INDEX(layer);
2015 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
2016 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
2017
2018 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
2019
2/2
✓ Branch 0 taken 108690957 times.
✓ Branch 1 taken 39913373 times.
148604330 if (get_qr(qr_SMARTER_WATER))
2020 {
2021
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 108690957 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
108690957 if (DRIEDLAKE) return 0;
2022
5/6
✓ Branch 0 taken 32426398 times.
✓ Branch 1 taken 76264559 times.
✓ Branch 2 taken 6533834 times.
✓ Branch 3 taken 25892564 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6533834 times.
108690957 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
2023 {
2024
2/2
✓ Branch 0 taken 75506100 times.
✓ Branch 1 taken 24802551 times.
100308651 for (int32_t m = layer; m <= 1; m++)
2025 {
2026
5/6
✓ Branch 0 taken 49613536 times.
✓ Branch 1 taken 25892564 times.
✓ Branch 2 taken 24809766 times.
✓ Branch 3 taken 24803770 times.
✓ Branch 4 taken 24803770 times.
✗ Branch 5 not taken.
100309870 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
2027
1/2
✓ Branch 0 taken 24803770 times.
✗ Branch 1 not taken.
49613536 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
2028 {
2029 75506100 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
2030
2/2
✓ Branch 0 taken 74416087 times.
✓ Branch 1 taken 1090013 times.
75506100 if (checkwater > 0)
2031 {
2032
2/2
✓ Branch 0 taken 1089930 times.
✓ Branch 1 taken 83 times.
1090013 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
2033 1090013 return checkwater;
2034 }
2035 74416087 }
2036 74416087 }
2037 24802551 return 0;
2038 }
2039 else
2040 {
2041
2/2
✓ Branch 0 taken 82822037 times.
✓ Branch 1 taken 78270620 times.
161092657 for(int32_t i=(fullcheck?3:0); i>=0; i--)
2042 {
2043 82822037 int32_t tx2=((i&2)<<2)+x;
2044 82822037 int32_t ty2=((i&1)<<3)+y;
2045 82822037 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
2046 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
2047
2/2
✓ Branch 0 taken 36073 times.
✓ Branch 1 taken 82785964 times.
82822037 if (!fullcheck)
2048 {
2049 82785964 tx2 = x;
2050 82785964 ty2 = y;
2051
2/2
✓ Branch 0 taken 45283751 times.
✓ Branch 1 taken 37502213 times.
82785964 if(tx2&8) b+=2;
2052
2/2
✓ Branch 0 taken 39266539 times.
✓ Branch 1 taken 43519425 times.
82785964 if(ty2&8) b+=1;
2053 82785964 }
2054
2/2
✓ Branch 0 taken 171615549 times.
✓ Branch 1 taken 80378864 times.
251994413 for (int32_t m = layer; m <= 1; m++)
2055 {
2056 171615549 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
2057
3/6
✓ Branch 0 taken 169428046 times.
✓ Branch 1 taken 2187503 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 169428046 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
171615549 if (hero && cmb.dive_under_level && (Hero.get_standing_z_state() <= -cmb.dive_under_level))
2058 continue; // dive under this layer
2059
2060
2/2
✓ Branch 0 taken 17728431 times.
✓ Branch 1 taken 153887118 times.
171615549 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2061 {
2062
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17728431 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17728431 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
2063 {
2064 return 0;
2065 }
2066 17728431 }
2067 else
2068 {
2069
4/4
✓ Branch 0 taken 253102 times.
✓ Branch 1 taken 153634016 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 201950 times.
153887118 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
2070 {
2071 201950 return 0;
2072 }
2073 }
2074
2/2
✓ Branch 0 taken 17728431 times.
✓ Branch 1 taken 153685168 times.
171413599 if (get_qr(qr_NO_SOLID_SWIM))
2075 {
2076
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 153634016 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2241223 times.
✓ Branch 5 taken 151392793 times.
✓ Branch 6 taken 34499 times.
✓ Branch 7 taken 2206724 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 34499 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
153685168 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
2077 2241223 return 0;
2078 151443945 }
2079
3/6
✓ Branch 0 taken 497938 times.
✓ Branch 1 taken 168674438 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 497938 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
169172376 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
2080 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
2081 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
2082 {
2083 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
2084 }
2085 169172376 }
2086
2087 223141593 auto found_ffc_not_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2088
2/2
✓ Branch 0 taken 141975938 times.
✓ Branch 1 taken 786791 times.
142762729 if (ffcIsAt(ffc_handle, tx2, ty2))
2089 {
2090 786791 auto ty = ffc_handle.ctype();
2091
4/6
✓ Branch 0 taken 786791 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193850 times.
✓ Branch 3 taken 592941 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 193850 times.
786791 if(!combo_class_buf[ty].water && !(ShallowCheck && ty == cSHALLOWWATER))
2092 786791 return true;
2093 }
2094
2095 141975938 return false;
2096 142762729 });
2097
2/2
✓ Branch 0 taken 79592073 times.
✓ Branch 1 taken 786791 times.
80378864 if (found_ffc_not_water) return 0;
2098
2099
2/2
✓ Branch 0 taken 23644 times.
✓ Branch 1 taken 79568429 times.
79592073 if(!i)
2100 {
2101 219033153 auto found_ffc_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2102
1/2
✓ Branch 0 taken 139464724 times.
✗ Branch 1 not taken.
139464724 if (ffcIsAt(ffc_handle, tx2, ty2))
2103 {
2104 auto ty = ffc_handle.ctype();
2105 if(combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER))
2106 return true;
2107 }
2108
2109 139464724 return false;
2110 139464724 });
2111
1/2
✓ Branch 0 taken 79568429 times.
✗ Branch 1 not taken.
79568429 if (found_ffc_water)
2112 {
2113 if(out_handle) *out_handle = *found_ffc_water;
2114 return found_ffc_water->data();
2115 }
2116 79568429 }
2117
2118 79592073 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2119
2/2
✓ Branch 0 taken 79547579 times.
✓ Branch 1 taken 44494 times.
79592073 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2120
7/12
✓ Branch 0 taken 79117557 times.
✓ Branch 1 taken 430022 times.
✓ Branch 2 taken 16988996 times.
✓ Branch 3 taken 62128561 times.
✓ Branch 4 taken 16164126 times.
✓ Branch 5 taken 824870 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 16164126 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
79547579 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2121 {
2122
2/2
✓ Branch 0 taken 1577 times.
✓ Branch 1 taken 1253315 times.
1254892 if (i == 0)
2123 {
2124
2/2
✓ Branch 0 taken 1253306 times.
✓ Branch 1 taken 9 times.
1253315 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2125 1253315 return checkcombo;
2126 }
2127 1577 }
2128 78294264 }
2129 78270620 return 0;
2130 }
2131 }
2132 else
2133 {
2134 39913373 int32_t b = 0;
2135
2/2
✓ Branch 0 taken 20700324 times.
✓ Branch 1 taken 19213049 times.
39913373 if(x&8) b+=2;
2136
2/2
✓ Branch 0 taken 15520397 times.
✓ Branch 1 taken 24392976 times.
39913373 if(y&8) b+=1;
2137
1/2
✓ Branch 0 taken 39913373 times.
✗ Branch 1 not taken.
39913373 if (get_qr(qr_NO_SOLID_SWIM))
2138 {
2139 if (combobuf[combo].walk&(1<<b))
2140 {
2141 return 0;
2142 }
2143 }
2144
1/2
✓ Branch 0 taken 39913373 times.
✗ Branch 1 not taken.
39913373 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2145
8/8
✓ Branch 0 taken 38150901 times.
✓ Branch 1 taken 1762472 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982956 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1778552 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 165477 times.
39913373 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2146 {
2147
2/2
✓ Branch 0 taken 1943999 times.
✓ Branch 1 taken 30 times.
1944029 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2148 1944029 return combo;
2149 }
2150 38146730 return 0;
2151 }
2152 148781716 }
2153
2154 354 bool isdamage_type(int32_t type)
2155 {
2156
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 28 times.
354 switch(type)
2157 {
2158 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2159 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2160 28 return true;
2161 }
2162 326 return false;
2163 354 }
2164
2165 2230586164 bool ispitfall_type(int32_t type)
2166 {
2167 2230586164 return combo_class_buf[type].pit != 0;
2168 }
2169
2170 2230586164 bool ispitfall(int32_t combo)
2171 {
2172 2230586164 return ispitfall_type(combobuf[combo].type);
2173 }
2174
2175 138848465 bool ispitfall(int32_t x, int32_t y)
2176 {
2177
2/2
✓ Branch 0 taken 1303540 times.
✓ Branch 1 taken 137544925 times.
138848465 if(int32_t c = MAPFFCOMBO(x,y))
2178 {
2179 1303540 return ispitfall(c) ? true : false;
2180 }
2181 137544925 int32_t c = MAPCOMBOL(2,x,y);
2182
2/2
✓ Branch 0 taken 77 times.
✓ Branch 1 taken 137544848 times.
137544925 if(ispitfall(c)) return true;
2183
2/2
✓ Branch 0 taken 122656443 times.
✓ Branch 1 taken 14888405 times.
137544848 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2184 {
2185
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122656443 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122656443 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2186 122656443 }
2187 else
2188 {
2189
3/4
✓ Branch 0 taken 16383 times.
✓ Branch 1 taken 14872022 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 16383 times.
14888405 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2190 }
2191 137528465 c = MAPCOMBOL(1,x,y);
2192
2/2
✓ Branch 0 taken 19968 times.
✓ Branch 1 taken 137508497 times.
137528465 if(ispitfall(c)) return true;
2193
2194
2/2
✓ Branch 0 taken 122656443 times.
✓ Branch 1 taken 14852054 times.
137508497 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2195 {
2196
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 122656443 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
122656443 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2197 122656443 }
2198 else
2199 {
2200
4/4
✓ Branch 0 taken 16533 times.
✓ Branch 1 taken 14835521 times.
✓ Branch 2 taken 12238 times.
✓ Branch 3 taken 4295 times.
14852054 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2201 }
2202 137496259 c = MAPCOMBO(x,y);
2203
2/2
✓ Branch 0 taken 59028 times.
✓ Branch 1 taken 137437231 times.
137496259 if(ispitfall(c)) return true;
2204 137437231 return false;
2205 138848465 }
2206
2207 612001743 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2208 {
2209
2/2
✓ Branch 0 taken 9485176 times.
✓ Branch 1 taken 602516567 times.
612001743 if(int32_t c = MAPFFCOMBO(x,y))
2210 {
2211
2/2
✓ Branch 0 taken 845 times.
✓ Branch 1 taken 9484331 times.
9485176 return ispitfall(c) ? c : 0;
2212 }
2213 602516567 int32_t c = MAPCOMBOL(2,x,y);
2214
2/2
✓ Branch 0 taken 1362 times.
✓ Branch 1 taken 602515205 times.
602516567 if(ispitfall(c)) return c;
2215
2216
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 69792720 times.
602515205 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2217 {
2218
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2219 532722485 }
2220 else
2221 {
2222
3/4
✓ Branch 0 taken 81755 times.
✓ Branch 1 taken 69710965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 81755 times.
69792720 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2223 }
2224 602433450 c = MAPCOMBOL(1,x,y);
2225
2/2
✓ Branch 0 taken 25192 times.
✓ Branch 1 taken 602408258 times.
602433450 if(ispitfall(c)) return c;
2226
2227
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 69685773 times.
602408258 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2228 {
2229
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2230 532722485 }
2231 else
2232 {
2233
4/4
✓ Branch 0 taken 171385 times.
✓ Branch 1 taken 69514388 times.
✓ Branch 2 taken 130757 times.
✓ Branch 3 taken 40628 times.
69685773 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2234 }
2235 602277501 c = MAPCOMBO(x,y);
2236
2/2
✓ Branch 0 taken 200737 times.
✓ Branch 1 taken 602076764 times.
602277501 if(ispitfall(c)) return c;
2237 602076764 return 0;
2238 612001743 }
2239 99 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2240 {
2241
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 98 times.
99 if(int32_t c = MAPFFCOMBO(x,y))
2242 {
2243
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2244 }
2245 98 int32_t c = MAPCOMBOL(2,x,y);
2246
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 97 times.
98 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2247
2248
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 91 times.
97 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2249 {
2250
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2251 return nullopt;
2252 6 }
2253 else
2254 {
2255
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
91 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2256 return nullopt;
2257 }
2258 97 c = MAPCOMBOL(1,x,y);
2259
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 85 times.
97 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2260
2261
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 79 times.
85 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2262 {
2263
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2264 return nullopt;
2265 6 }
2266 else
2267 {
2268
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 79 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
79 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2269 return nullopt;
2270 }
2271 85 c = MAPCOMBO(x,y);
2272
1/2
✓ Branch 0 taken 85 times.
✗ Branch 1 not taken.
85 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2273 return nullopt;
2274 99 }
2275 11915697 bool check_icy(newcombo const& cmb, int type)
2276 {
2277
2/2
✓ Branch 0 taken 11915532 times.
✓ Branch 1 taken 165 times.
11915697 if(cmb.type != cICY)
2278 11915532 return false;
2279
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
165 switch(type)
2280 {
2281 case ICY_BLOCK:
2282 return cmb.usrflags&cflag1;
2283 case ICY_PLAYER:
2284 165 return cmb.usrflags&cflag2;
2285 }
2286 return false;
2287 11915697 }
2288 3977849 int get_icy(int x, int y, int type)
2289 {
2290 3977849 int32_t c = MAPCOMBOL(2,x,y);
2291
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3977849 times.
3977849 if(check_icy(combobuf[c], type)) return c;
2292
2293 3977849 int screen = get_screen_for_world_xy(x, y);
2294
2295 3977849 mapscr* scr = get_scr_layer_valid(screen, 2);
2296
2/2
✓ Branch 0 taken 33063 times.
✓ Branch 1 taken 3944786 times.
3977849 if (scr)
2297 {
2298
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 3944270 times.
3944786 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2299 {
2300
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2301 516 }
2302 else
2303 {
2304
3/4
✓ Branch 0 taken 6663 times.
✓ Branch 1 taken 3937607 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6663 times.
3944270 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2305 }
2306 3938123 }
2307 3971186 c = MAPCOMBOL(1,x,y);
2308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3971186 times.
3971186 if(check_icy(combobuf[c], type)) return c;
2309
2310 3971186 scr = get_scr_layer_valid(screen, 1);
2311
2/2
✓ Branch 0 taken 15202 times.
✓ Branch 1 taken 3955984 times.
3971186 if (scr)
2312 {
2313
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 3954050 times.
3955984 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2314 {
2315
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2316 1934 }
2317 else
2318 {
2319
3/4
✓ Branch 0 taken 4689 times.
✓ Branch 1 taken 3949361 times.
✓ Branch 2 taken 4689 times.
✗ Branch 3 not taken.
3954050 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2320 }
2321 3951295 }
2322 3966497 c = MAPCOMBO(x,y);
2323
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3966497 times.
3966497 if(check_icy(combobuf[c], type)) return c;
2324 3966497 return 0;
2325 3977849 }
2326
2327 13252199 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2328 {
2329
8/8
✓ Branch 0 taken 13245401 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13236535 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13224903 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 434748 times.
✓ Branch 7 taken 12790155 times.
13252199 if(x<0 || x>=world_w || y<0 || y>=world_h)
2330 462044 return false;
2331
2332 12790155 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2333
2/4
✓ Branch 0 taken 12790155 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12790155 times.
12790155 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2334 return true;
2335
2336 12790155 change_rpos_handle_layer(rpos_handle, 1);
2337
2/2
✓ Branch 0 taken 7562878 times.
✓ Branch 1 taken 5227277 times.
12790155 if (rpos_handle.scr->is_valid())
2338
3/4
✓ Branch 0 taken 5227277 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3279 times.
✓ Branch 3 taken 5223998 times.
5227277 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2339 3279 return true;
2340
2341 12786876 change_rpos_handle_layer(rpos_handle, 2);
2342
2/2
✓ Branch 0 taken 10846680 times.
✓ Branch 1 taken 1940196 times.
12786876 if (rpos_handle.scr->is_valid())
2343
3/4
✓ Branch 0 taken 1940196 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 1940115 times.
1940196 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2344 81 return true;
2345
2346 12786795 return false;
2347 13252199 }
2348
2349 6690282 bool isSVLadder(int32_t x, int32_t y)
2350 {
2351 6690282 return checkSV(x, y, mfSIDEVIEWLADDER);
2352 }
2353
2354 6561917 bool isSVPlatform(int32_t x, int32_t y)
2355 {
2356 6561917 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2357 }
2358
2359 6561917 bool checkSVLadderPlatform(int32_t x, int32_t y)
2360 {
2361
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6561917 times.
✓ Branch 2 taken 6560079 times.
✓ Branch 3 taken 1838 times.
6561917 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2362 }
2363
2364 4206 bool isstepable(int32_t combo) //can use ladder on it
2365 {
2366
2/2
✓ Branch 0 taken 4200 times.
✓ Branch 1 taken 6 times.
4206 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2367
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2368 {
2369 if(combobuf[combo].usrflags&cflag4)
2370 {
2371 int32_t ldrid = current_item_id(itype_ladder);
2372 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2373 }
2374 }
2375 6 return false;
2376 4206 }
2377
2378 33016 bool isHSGrabbable(newcombo const& cmb)
2379 {
2380
2/2
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 32639 times.
33016 if(cmb.type == cHSGRAB) return true;
2381 32639 return cmb.genflags & cflag1;
2382 33016 }
2383
2384 954 bool isSwitchHookable(newcombo const& cmb)
2385 {
2386
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2387 822 return cmb.genflags & cflag2;
2388 954 }
2389
2390 62207 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2391 {
2392 62207 rpos_t cpos = rpos_t::None;
2393
2/2
✓ Branch 0 taken 65056 times.
✓ Branch 1 taken 127263 times.
62207 if(out_rpos)
2394 {
2395 127263 int32_t id = MAPCOMBO2(layer-1,x,y);
2396
2/2
✓ Branch 0 taken 29204 times.
✓ Branch 1 taken 98059 times.
127263 if(id > 0)
2397 {
2398 98059 newcombo const& cmb = combobuf[id];
2399
4/4
✓ Branch 0 taken 32974 times.
✓ Branch 1 taken 65085 times.
✓ Branch 2 taken 32528 times.
✓ Branch 3 taken 32557 times.
98059 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2400 33003 }
2401 62207 }
2402
2403 127263 ffcdata* ffc = nullptr;
2404
4/4
✓ Branch 0 taken 28531 times.
✓ Branch 1 taken 98732 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3535 times.
127263 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2405 {
2406 10645 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2407
2/2
✓ Branch 0 taken 6995 times.
✓ Branch 1 taken 115 times.
7110 if (ffcIsAt(ffc_handle, x, y))
2408 {
2409 115 auto& cmb = ffc_handle.combo();
2410
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 73 times.
✓ Branch 2 taken 37 times.
✓ Branch 3 taken 36 times.
115 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2411 {
2412 79 ffc = ffc_handle.ffc;
2413 79 return false;
2414 }
2415 36 }
2416 7031 return true;
2417 7038 });
2418 3535 }
2419
2420
4/4
✓ Branch 0 taken 62207 times.
✓ Branch 1 taken 65056 times.
✓ Branch 2 taken 446 times.
✓ Branch 3 taken 61761 times.
127263 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2421
4/4
✓ Branch 0 taken 28531 times.
✓ Branch 1 taken 98732 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28524 times.
127263 if (out_ffc && ffc) *out_ffc = ffc;
2422
2/2
✓ Branch 0 taken 65502 times.
✓ Branch 1 taken 61761 times.
127263 return (cpos != rpos_t::None || ffc);
2423 }
2424
2425 5199 bool ishookshottable(int32_t bx, int32_t by)
2426 {
2427
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5199 times.
5199 if(!_walkflag(bx,by,1))
2428 return true;
2429
2430
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5191 times.
5199 if (collide_object(bx, by, 1, 1))
2431 8 return false;
2432
2433 5191 bool ret = true;
2434
2/2
✓ Branch 0 taken 15573 times.
✓ Branch 1 taken 1904 times.
17477 for(int32_t i=2; i>=0; i--)
2435 {
2436 15573 int32_t c = MAPCOMBO2(i-1,bx,by);
2437 15573 int32_t t = combobuf[c].type;
2438
2439
6/6
✓ Branch 0 taken 5191 times.
✓ Branch 1 taken 10382 times.
✓ Branch 2 taken 3857 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1904 times.
✓ Branch 5 taken 1953 times.
15573 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2440
2441
3/4
✓ Branch 0 taken 11333 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13239 bool dried = (iswater_type(t) && DRIEDLAKE);
2442
2443 12286 int32_t b=1;
2444
2445
2/2
✓ Branch 0 taken 6112 times.
✓ Branch 1 taken 6174 times.
12286 if(bx&8) b<<=2;
2446
2447
2/2
✓ Branch 0 taken 3853 times.
✓ Branch 1 taken 8433 times.
12286 if(by&8) b<<=1;
2448
2449
7/8
✓ Branch 0 taken 2098 times.
✓ Branch 1 taken 10188 times.
✓ Branch 2 taken 2098 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 983 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 908 times.
12286 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2450 908 ret = false;
2451 12286 }
2452
2453 1904 return ret;
2454 5199 }
2455
2456 11108 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2457 {
2458
4/4
✓ Branch 0 taken 10529 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 10529 times.
✓ Branch 3 taken 579 times.
11108 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2459 {
2460 579 int pos = COMBOPOS(s->stairx,s->stairy);
2461 579 s->data[pos] = s->secretcombo[sSTAIRS];
2462 579 s->cset[pos] = s->secretcset[sSTAIRS];
2463 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2464
2465
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2466 {
2467 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2468 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2469 256 }
2470
2471 579 return true;
2472 }
2473
2474 10529 return false;
2475 11108 }
2476
2477 52904 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2478 {
2479 DCHECK(base_scr->is_valid());
2480
2481 52904 screen_handles_t screen_handles{};
2482 52904 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2483 52904 return screen_handles;
2484 }
2485
2486 58562664 screen_handles_t create_screen_handles(mapscr* base_scr)
2487 {
2488 DCHECK(get_scr(base_scr->screen) == base_scr);
2489 DCHECK(base_scr->is_valid());
2490
2491 58562664 int screen = base_scr->screen;
2492 screen_handles_t screen_handles;
2493 58562664 screen_handles[0] = {base_scr, base_scr, screen, 0};
2494
2/2
✓ Branch 0 taken 351375984 times.
✓ Branch 1 taken 58562664 times.
409938648 for (int i = 1; i <= 6; i++)
2495 351375984 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2496 58562664 return screen_handles;
2497 }
2498
2499 113471 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2500 {
2501 113471 mapscr* scr = screen_handles[0].scr;
2502 113471 bool didit=false;
2503
2504
2/2
✓ Branch 0 taken 113471 times.
✓ Branch 1 taken 19970896 times.
20084367 for(int32_t i=0; i<176; i++)
2505 {
2506 19970896 newcombo const& cmb = combobuf[scr->data[i]];
2507
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 19970570 times.
19970896 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2508
4/4
✓ Branch 0 taken 19968994 times.
✓ Branch 1 taken 1576 times.
✓ Branch 2 taken 1134 times.
✓ Branch 3 taken 19967860 times.
19970570 if((cmb.type == what1) || (cmb.type== what2))
2509 {
2510 2710 scr->data[i]++;
2511 2710 didit=true;
2512 2710 }
2513 19970570 }
2514
2515
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 113379 times.
113471 if (do_layers)
2516 {
2517
2/2
✓ Branch 0 taken 680274 times.
✓ Branch 1 taken 113379 times.
793653 for(int32_t j=1; j<=6; j++)
2518 {
2519 680274 mapscr* layer_scr = screen_handles[j].scr;
2520
2/2
✓ Branch 0 taken 195881 times.
✓ Branch 1 taken 484393 times.
680274 if (!layer_scr) continue;
2521
2522
2/2
✓ Branch 0 taken 34475056 times.
✓ Branch 1 taken 195881 times.
34670937 for(int32_t i=0; i<176; i++)
2523 {
2524 34475056 newcombo const& cmb = combobuf[layer_scr->data[i]];
2525
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34475056 times.
34475056 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2526
4/4
✓ Branch 0 taken 34474741 times.
✓ Branch 1 taken 315 times.
✓ Branch 2 taken 319 times.
✓ Branch 3 taken 34474422 times.
34475056 if((cmb.type== what1) || (cmb.type== what2))
2527 {
2528 634 layer_scr->data[i]++;
2529 634 didit=true;
2530 634 }
2531 34475056 }
2532 195881 }
2533 113379 }
2534
2535 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2536
3/4
✓ Branch 0 taken 27675 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 27675 times.
113471 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2537 {
2538 27675 word c = scr->numFFC();
2539
2/2
✓ Branch 0 taken 80883 times.
✓ Branch 1 taken 27675 times.
108558 for(word i=0; i<c; i++)
2540 {
2541 80883 ffcdata* ffc = &scr->ffcs[i];
2542 80883 newcombo const& cmb = combobuf[ffc->data];
2543
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80883 times.
80883 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2544
2/4
✓ Branch 0 taken 80883 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 80883 times.
80883 if((cmb.type== what1) || (cmb.type== what2))
2545 {
2546 zc_ffc_modify(*ffc, 1);
2547 didit=true;
2548 }
2549 80883 }
2550 27675 }
2551
2552 113471 return didit;
2553 }
2554
2555 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2556 {
2557 14 int screen = screen_handles[0].scr->screen;
2558
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2559 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2560 }
2561 488350862 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2562 {
2563 488350862 bool didit=false;
2564
2/2
✓ Branch 0 taken 488309901 times.
✓ Branch 1 taken 40961 times.
488350862 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2565
2566 40961 mapscr* s = screen_handles[0].scr;
2567 40961 int screen = s->screen;
2568 40961 bool is_active_screen = is_in_current_region(s);
2569
2570 34122305 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2571
4/4
✓ Branch 0 taken 49456 times.
✓ Branch 1 taken 34031888 times.
✓ Branch 2 taken 1891 times.
✓ Branch 3 taken 34079453 times.
34081344 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2572 1891 didit = true;
2573
2/2
✓ Branch 0 taken 64673 times.
✓ Branch 1 taken 34014780 times.
34079453 else switch (rpos_handle.ctype())
2574 {
2575 case cLOCKBLOCK: case cLOCKBLOCK2:
2576 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2577 case cCHEST: case cCHEST2:
2578 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2579 case cBOSSCHEST: case cBOSSCHEST2:
2580 {
2581 64673 auto& cmb = rpos_handle.combo();
2582
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 2614 times.
64673 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2583
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2584 {
2585 29 rpos_handle.increment_data();
2586 29 didit=true;
2587 29 }
2588 62059 break;
2589 }
2590 }
2591 34081344 });
2592
2593
4/4
✓ Branch 0 taken 40889 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 31269 times.
✓ Branch 3 taken 9620 times.
40961 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2594 {
2595 31269 word c = s->numFFC();
2596 31269 int screen_index_offset = get_region_screen_offset(screen);
2597
2/2
✓ Branch 0 taken 65746 times.
✓ Branch 1 taken 31269 times.
97015 for (uint8_t i = 0; i < c; i++)
2598 {
2599 65746 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2600 65746 auto& cmb = ffc_handle.combo();
2601
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 65746 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 65730 times.
65746 if(triggers && force_ex_trigger_any(ffc_handle, xflag))
2602 16 didit = true;
2603
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65730 times.
65730 else switch(cmb.type)
2604 {
2605 case cLOCKBLOCK: case cLOCKBLOCK2:
2606 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2607 case cCHEST: case cCHEST2:
2608 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2609 case cBOSSCHEST: case cBOSSCHEST2:
2610 {
2611 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2612 if(cmb.attribytes[5] == xflag)
2613 {
2614 zc_ffc_modify(*ffc_handle.ffc, 1);
2615 didit=true;
2616 }
2617 break;
2618 }
2619 }
2620 65746 }
2621 31269 }
2622
2623 40961 return didit;
2624 488350862 }
2625
2626 15207837 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2627 {
2628 15207837 int screen = screen_handles[0].screen;
2629
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14820004 times.
15207837 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2630 15207837 clear_xstatecombos_mi(screen_handles, mi, triggers);
2631 15207837 }
2632
2633 15260964 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2634 {
2635
2/2
✓ Branch 0 taken 488350848 times.
✓ Branch 1 taken 15260964 times.
503611812 for (int q = 0; q < 32; ++q)
2636 {
2637 488350848 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2638 488350848 }
2639 15260964 }
2640
2641 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2642 {
2643 int screen = screen_handles[0].screen;
2644 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2645 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2646 }
2647 488350848 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2648 {
2649 488350848 bool didit=false;
2650
2/2
✓ Branch 0 taken 488349535 times.
✓ Branch 1 taken 1313 times.
488350848 if (!getxdoor_mi(mi, dir, ind)) return false;
2651
2652 1313 mapscr* scr = screen_handles[0].scr;
2653 1313 int screen = scr->screen;
2654 1313 bool is_active_screen = is_in_current_region(scr);
2655
2656 925665 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2657
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 924352 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 924341 times.
924352 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2658 11 didit = true;
2659 else; //future door combo types?
2660 924352 });
2661
2662
2/4
✓ Branch 0 taken 1313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1313 times.
✗ Branch 3 not taken.
1313 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2663 {
2664 1313 word c = scr->numFFC();
2665 1313 int screen_index_offset = get_region_screen_offset(screen);
2666
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1313 times.
1313 for (uint8_t i = 0; i < c; i++)
2667 {
2668 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2669 if (triggers && force_ex_door_trigger_any(ffc_handle, dir, ind))
2670 didit = true;
2671 else; //future door combo types?
2672 }
2673 1313 }
2674
2675 1313 return didit;
2676 488350848 }
2677
2678 15207837 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2679 {
2680 15207837 int screen = screen_handles[0].screen;
2681
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14820004 times.
15207837 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2682 15207837 return clear_xdoors_mi(screen_handles, mi, triggers);
2683 }
2684
2685 15260964 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2686 {
2687
2/2
✓ Branch 0 taken 61043856 times.
✓ Branch 1 taken 15260964 times.
76304820 for (int dir = 0; dir < 4; ++dir)
2688
2/2
✓ Branch 0 taken 488350848 times.
✓ Branch 1 taken 61043856 times.
549394704 for (int q = 0; q < 8; ++q)
2689 549394704 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2690 15260964 }
2691
2692 885 bool remove_lockblocks(const screen_handles_t& screen_handles)
2693 {
2694 885 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2695 }
2696
2697 139 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2698 {
2699 139 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2700 }
2701
2702 83659 bool remove_chests(const screen_handles_t& screen_handles)
2703 {
2704 83659 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2705 }
2706
2707 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2708 {
2709 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2710 }
2711
2712 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2713 {
2714 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2715 }
2716
2717 1418795 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2718 {
2719 1418795 int32_t ct=rpos_handle.ctype();
2720
2721
6/6
✓ Branch 0 taken 1418175 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1417923 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1417815 times.
✓ Branch 5 taken 108 times.
1418795 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2722 1417815 return;
2723
2724 2465 auto [cx, cy] = rpos_handle.xy();
2725
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2726 {
2727 case cL_STATUE:
2728 620 cx += 4;
2729 620 cy += 7;
2730 620 break;
2731
2732 case cR_STATUE:
2733 252 cx -= 8;
2734 252 cy -= 1;
2735 252 break;
2736
2737 case cC_STATUE:
2738 108 break;
2739 }
2740
2741
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2742 {
2743 // Finds the smallest enemy ID
2744
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2745 {
2746 346 guys.del(j);
2747 346 }
2748 1485 }
2749 1418795 }
2750
2751 45 static int32_t findtrigger(int32_t screen)
2752 {
2753 45 int32_t checkflag=0;
2754 45 int32_t ret = 0;
2755
2756 mapscr* screens[7];
2757
2/2
✓ Branch 0 taken 315 times.
✓ Branch 1 taken 45 times.
360 for (int32_t j = 0; j <= 6; j++)
2758 {
2759 315 screens[j] = get_scr_layer_valid(screen, j);
2760 315 }
2761
2762 45 bool sflag = false;
2763
2/2
✓ Branch 0 taken 7920 times.
✓ Branch 1 taken 45 times.
7965 for(word j=0; j<176; j++)
2764 {
2765
2/2
✓ Branch 0 taken 87648 times.
✓ Branch 1 taken 7920 times.
95568 for(int32_t layer = -1; layer < 6; ++layer)
2766 {
2767 87648 mapscr* scr = screens[layer+1];
2768
2/2
✓ Branch 0 taken 64416 times.
✓ Branch 1 taken 23232 times.
87648 if (!scr) continue;
2769
2770
2/2
✓ Branch 0 taken 32208 times.
✓ Branch 1 taken 32208 times.
64416 if(sflag)
2771 32208 checkflag = scr->sflag[j];
2772 else
2773 32208 checkflag = combobuf[scr->data[j]].flag;
2774 64416 sflag = !sflag;
2775
2/2
✓ Branch 0 taken 32208 times.
✓ Branch 1 taken 32208 times.
64416 if (sflag) --layer;
2776
2777
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 64374 times.
64416 switch(checkflag)
2778 {
2779 case mfANYFIRE:
2780 case mfSTRONGFIRE:
2781 case mfMAGICFIRE:
2782 case mfDIVINEFIRE:
2783 case mfARROW:
2784 case mfSARROW:
2785 case mfGARROW:
2786 case mfSBOMB:
2787 case mfBOMB:
2788 case mfBRANG:
2789 case mfMBRANG:
2790 case mfFBRANG:
2791 case mfWANDMAGIC:
2792 case mfREFMAGIC:
2793 case mfREFFIREBALL:
2794 case mfSWORD:
2795 case mfWSWORD:
2796 case mfMSWORD:
2797 case mfXSWORD:
2798 case mfSWORDBEAM:
2799 case mfWSWORDBEAM:
2800 case mfMSWORDBEAM:
2801 case mfXSWORDBEAM:
2802 case mfHOOKSHOT:
2803 case mfWAND:
2804 case mfHAMMER:
2805 case mfSTRIKE:
2806 42 ret += 1;
2807 42 break;
2808 }
2809 64416 }
2810 7920 }
2811
2812 45 return ret;
2813 }
2814
2815 12340 static void log_trigger_secret_reason(TriggerSource source)
2816 {
2817
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11888 times.
12340 if (source == TriggerSource::Singular)
2818 {
2819 452 Z_eventlog("Restricted Screen Secrets triggered\n");
2820 452 }
2821 else
2822 {
2823 11888 const char* source_str = "";
2824
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7297 times.
✓ Branch 3 taken 897 times.
✓ Branch 4 taken 3114 times.
✓ Branch 5 taken 500 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 75 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11888 switch (source)
2825 {
2826 case TriggerSource::Singular: break;
2827 7297 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2828 897 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2829 3114 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2830 500 case TriggerSource::Script: source_str = "a script"; break;
2831 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2832 75 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2833 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2834 case TriggerSource::SCC: source_str = "SCC"; break;
2835 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2836 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2837 }
2838 11888 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2839 }
2840 12340 }
2841
2842 // single:
2843 // >-1 : the singular triggering combo
2844 // -1: triggered by some other cause
2845 12132 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2846 {
2847 12132 log_trigger_secret_reason(source);
2848
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11680 times.
12132 if (single < 0)
2849 11680 get_screen_state(scr->screen).triggered_secrets = true;
2850
2851 12132 bool do_replay_comment = true;
2852 12132 bool from_active_screen = true;
2853 12132 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2854
2855 // Respect secret state carryovers for active screens.
2856
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 11680 times.
12132 if (single >= 0) return;
2857
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 11655 times.
11680 if(scr->nocarry&mSECRET) return;
2858 11655 int cmap = scr->map;
2859 11655 int cscr = scr->screen;
2860 11655 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2861 11655 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2862
2863 11655 std::vector<int32_t> done;
2864
2/2
✓ Branch 0 taken 11450 times.
✓ Branch 1 taken 205 times.
11655 bool looped = (nmap==cmap+1 && nscr==cscr);
2865
2866
6/6
✓ Branch 0 taken 586 times.
✓ Branch 1 taken 11569 times.
✓ Branch 2 taken 86 times.
✓ Branch 3 taken 500 times.
✓ Branch 4 taken 500 times.
✓ Branch 5 taken 11655 times.
12155 while((nmap!=0) && !looped && !(nscr>=128))
2867 {
2868
7/8
✓ Branch 0 taken 388 times.
✓ Branch 1 taken 112 times.
✓ Branch 2 taken 93 times.
✓ Branch 3 taken 295 times.
✓ Branch 4 taken 93 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 89 times.
500 if (nmap - 1 == cur_map && is_in_current_region(nscr) && !get_screen_state(nscr).triggered_secrets)
2869 {
2870
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2871
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2872
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2873 4 }
2874
2875 500 cmap=nmap;
2876 500 cscr=nscr;
2877 500 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2878 500 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2879
2880
2/2
✓ Branch 0 taken 443 times.
✓ Branch 1 taken 500 times.
943 for(auto it = done.begin(); it != done.end(); it++)
2881 {
2882
2/2
✓ Branch 0 taken 357 times.
✓ Branch 1 taken 86 times.
443 if(*it == ((nmap-1)<<7)+nscr)
2883 86 looped = true;
2884 443 }
2885
2886
1/2
✓ Branch 0 taken 500 times.
✗ Branch 1 not taken.
500 done.push_back(((nmap-1)<<7)+nscr);
2887 }
2888 12132 }
2889
2890 2550 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2891 {
2892 2550 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2893 2550 }
2894
2895 19223 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2896 {
2897 19223 mapscr* scr = screen_handles[0].scr;
2898 19223 int screen = scr->screen;
2899
2900 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2901 // slopes in sideview mode (which required loading nearby screens in loadscr).
2902 // TODO(replays): This should just use `screen`.
2903
3/4
✓ Branch 0 taken 19223 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 18684 times.
19223 if (replay_is_active() && do_replay_comment)
2904
4/6
✓ Branch 0 taken 12136 times.
✓ Branch 1 taken 6548 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12136 times.
✓ Branch 4 taken 18684 times.
✗ Branch 5 not taken.
18684 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2905
2906
2/2
✓ Branch 0 taken 7087 times.
✓ Branch 1 taken 12136 times.
19223 if (from_active_screen)
2907 {
2908 6099822 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2909
2/4
✓ Branch 0 taken 6085024 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2662 times.
✗ Branch 3 not taken.
6407603 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
2910 319917 return trig.trigger_flags.get(TRIGFLAG_SECRETSTR);
2911 }, ctrigSECRETS);
2912 6087686 });
2913 12136 }
2914
2915 19223 int32_t ft=0; //Flag trigger?
2916 19223 int32_t msflag=0; // Misc. secret flag
2917
2918
2/2
✓ Branch 0 taken 3383248 times.
✓ Branch 1 taken 19223 times.
3402471 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2919 {
2920
4/4
✓ Branch 0 taken 79552 times.
✓ Branch 1 taken 3303696 times.
✓ Branch 2 taken 452 times.
✓ Branch 3 taken 79100 times.
3383248 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2921
2922 // Remember the misc. secret flag; if triggered, use this instead
2923
4/4
✓ Branch 0 taken 153551 times.
✓ Branch 1 taken 3150597 times.
✓ Branch 2 taken 87558 times.
✓ Branch 3 taken 65993 times.
3304148 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2924 65993 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2925
4/4
✓ Branch 0 taken 47862 times.
✓ Branch 1 taken 3190293 times.
✓ Branch 2 taken 47336 times.
✓ Branch 3 taken 526 times.
3238155 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2926 526 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2927 else
2928 3237629 msflag=0;
2929
2930
4/4
✓ Branch 0 taken 922853 times.
✓ Branch 1 taken 2381295 times.
✓ Branch 2 taken 85 times.
✓ Branch 3 taken 922768 times.
3304148 if(!high16only || single>=0)
2931 {
2932 2381380 int32_t newflag = -1;
2933
2934
2/2
✓ Branch 0 taken 4762760 times.
✓ Branch 1 taken 2381380 times.
7144140 for(int32_t iter=0; iter<2; ++iter)
2935 {
2936 4762760 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2937
2938
2/2
✓ Branch 0 taken 2381380 times.
✓ Branch 1 taken 2381380 times.
4762760 if(iter==1) checkflag=scr->sflag[i]; //Placed
2939
2940 4762760 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2941
2/2
✓ Branch 0 taken 4750287 times.
✓ Branch 1 taken 12473 times.
4762760 if (ft != -1) //Change the combos for the secret
2942 {
2943 // Use misc. secret flag instead if one is present
2944
2/2
✓ Branch 0 taken 12441 times.
✓ Branch 1 taken 32 times.
12473 if(msflag!=0)
2945 32 ft=msflag;
2946
2947 12473 rpos_handle_t rpos_handle;
2948
2/2
✓ Branch 0 taken 6541 times.
✓ Branch 1 taken 5932 times.
12473 if (from_active_screen)
2949 {
2950 5932 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2951 5932 screen_combo_modify_preroutine(rpos_handle);
2952 5932 }
2953
2954
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12473 times.
12473 if(ft==sSECNEXT)
2955 {
2956 scr->data[i]++;
2957 }
2958 else
2959 {
2960 12473 scr->data[i] = scr->secretcombo[ft];
2961 12473 scr->cset[i] = scr->secretcset[ft];
2962 }
2963 12473 newflag = scr->secretflag[ft];
2964
2965
2/2
✓ Branch 0 taken 6541 times.
✓ Branch 1 taken 5932 times.
12473 if (from_active_screen)
2966 5932 screen_combo_modify_postroutine(rpos_handle);
2967 12473 }
2968 4762760 }
2969
2970
2/2
✓ Branch 0 taken 2368913 times.
✓ Branch 1 taken 12467 times.
2381380 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2971
2972
2/2
✓ Branch 0 taken 14288280 times.
✓ Branch 1 taken 2381380 times.
16669660 for(int32_t j=1; j<=6; j++) //Layers
2973 {
2974 14288280 mapscr* layer_scr = screen_handles[j].scr;
2975
2/2
✓ Branch 0 taken 4300978 times.
✓ Branch 1 taken 9987302 times.
14288280 if (!layer_scr) continue;
2976
2977
3/4
✓ Branch 0 taken 770 times.
✓ Branch 1 taken 4300208 times.
✓ Branch 2 taken 770 times.
✗ Branch 3 not taken.
4300978 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2978
2979 4300978 int32_t newflag2 = -1;
2980
2981 // Remember the misc. secret flag; if triggered, use this instead
2982
4/4
✓ Branch 0 taken 18068 times.
✓ Branch 1 taken 4282910 times.
✓ Branch 2 taken 6284 times.
✓ Branch 3 taken 11784 times.
4300978 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
2983 11784 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
2984
4/4
✓ Branch 0 taken 132026 times.
✓ Branch 1 taken 4157168 times.
✓ Branch 2 taken 130774 times.
✓ Branch 3 taken 1252 times.
4289194 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
2985 1252 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
2986 else
2987 4287942 msflag=0;
2988
2989
2/2
✓ Branch 0 taken 8601956 times.
✓ Branch 1 taken 4300978 times.
12902934 for(int32_t iter=0; iter<2; ++iter)
2990 {
2991 8601956 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
2992
2/2
✓ Branch 0 taken 4300978 times.
✓ Branch 1 taken 4300978 times.
8601956 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
2993
2994 8601956 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2995
2/2
✓ Branch 0 taken 8600177 times.
✓ Branch 1 taken 1779 times.
8601956 if (ft != -1) //Change the combos for the secret
2996 {
2997 // Use misc. secret flag instead if one is present
2998
2/2
✓ Branch 0 taken 1777 times.
✓ Branch 1 taken 2 times.
1779 if(msflag!=0)
2999 2 ft=msflag;
3000
3001
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1779 times.
1779 if(ft==sSECNEXT)
3002 {
3003 layer_scr->data[i]++;
3004 }
3005 else
3006 {
3007 1779 layer_scr->data[i] = layer_scr->secretcombo[ft];
3008 1779 layer_scr->cset[i] = layer_scr->secretcset[ft];
3009 }
3010 1779 newflag2 = layer_scr->secretflag[ft];
3011 1779 int32_t c=layer_scr->data[i];
3012 1779 int32_t cs=layer_scr->cset[i];
3013
3014
3/4
✓ Branch 0 taken 908 times.
✓ Branch 1 taken 871 times.
✓ Branch 2 taken 908 times.
✗ Branch 3 not taken.
1779 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
3015 {
3016 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
3017 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
3018 }
3019 1779 }
3020 8601956 }
3021
3022
2/2
✓ Branch 0 taken 1766 times.
✓ Branch 1 taken 4299212 times.
4300978 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
3023 4300978 }
3024 2381380 }
3025 3304148 }
3026
3027 19223 word c = scr->numFFC();
3028
2/2
✓ Branch 0 taken 508334 times.
✓ Branch 1 taken 19223 times.
527557 for(word i=0; i<c; i++) //FFC 'trigger flags'
3029 {
3030
3/4
✓ Branch 0 taken 494280 times.
✓ Branch 1 taken 14054 times.
✓ Branch 2 taken 14054 times.
✗ Branch 3 not taken.
508334 if(single>=0) if(i+176!=single) continue;
3031
3032
3/4
✓ Branch 0 taken 166649 times.
✓ Branch 1 taken 327631 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166649 times.
494280 if((!high16only)||(single>=0))
3033 {
3034 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
3035 {
3036 327631 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3037 //No placed flags yet
3038
3039 327631 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
3040
2/2
✓ Branch 0 taken 327600 times.
✓ Branch 1 taken 31 times.
327631 if (ft != -1) //Change the ffc's combo
3041 {
3042
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
3043 {
3044 zc_ffc_modify(scr->ffcs[i], 1);
3045 }
3046 else
3047 {
3048 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
3049 31 scr->ffcs[i].cset = scr->secretcset[ft];
3050 }
3051 31 }
3052 }
3053 327631 }
3054 494280 }
3055
3056
2/2
✓ Branch 0 taken 16725 times.
✓ Branch 1 taken 2498 times.
19223 if(checktrigger) //Hit all triggers->16-31
3057 {
3058 2498 checktrigger=false;
3059
3060
2/2
✓ Branch 0 taken 2474 times.
✓ Branch 1 taken 24 times.
2498 if(scr->flags6&fTRIGGERF1631)
3061 {
3062 24 int32_t tr = findtrigger(screen); //Normal flags
3063
3064
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 10 times.
24 if(tr)
3065 {
3066 14 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
3067 14 goto endhe;
3068 }
3069 10 }
3070 2484 }
3071
3072
2/2
✓ Branch 0 taken 3380784 times.
✓ Branch 1 taken 19209 times.
3399993 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
3073 {
3074 //If it's an enemies->secret screen, only do the high 16 if told to
3075 //That way you can have secret and burn/bomb entrance separately
3076 3380784 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
3077
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 600160 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3295600 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3380784 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
3078 {
3079 3315136 int32_t newflag = -1;
3080
3081
2/2
✓ Branch 0 taken 6630272 times.
✓ Branch 1 taken 3315136 times.
9945408 for(int32_t iter=0; iter<2; ++iter)
3082 {
3083 6630272 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
3084
3085
2/2
✓ Branch 0 taken 3315136 times.
✓ Branch 1 taken 3315136 times.
6630272 if(iter==1) checkflag=scr->sflag[i]; //Placed
3086
3087
4/4
✓ Branch 0 taken 200805 times.
✓ Branch 1 taken 6429467 times.
✓ Branch 2 taken 133230 times.
✓ Branch 3 taken 67575 times.
6630272 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3088 {
3089 67575 rpos_handle_t rpos_handle;
3090
2/2
✓ Branch 0 taken 10367 times.
✓ Branch 1 taken 57208 times.
67575 if (from_active_screen)
3091 {
3092 57208 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3093 57208 screen_combo_modify_preroutine(rpos_handle);
3094 57208 }
3095
3096 67575 scr->data[i] = scr->secretcombo[checkflag-16+4];
3097 67575 scr->cset[i] = scr->secretcset[checkflag-16+4];
3098 67575 newflag = scr->secretflag[checkflag-16+4];
3099
3100
2/2
✓ Branch 0 taken 10367 times.
✓ Branch 1 taken 57208 times.
67575 if (from_active_screen)
3101 57208 screen_combo_modify_postroutine(rpos_handle);
3102 67575 }
3103 6630272 }
3104
3105
2/2
✓ Branch 0 taken 3247589 times.
✓ Branch 1 taken 67547 times.
3315136 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3106
3107
2/2
✓ Branch 0 taken 19890816 times.
✓ Branch 1 taken 3315136 times.
23205952 for(int32_t j=1; j<=6; j++) //Layers
3108 {
3109 19890816 mapscr* layer_scr = screen_handles[j].scr;
3110
2/2
✓ Branch 0 taken 5992096 times.
✓ Branch 1 taken 13898720 times.
19890816 if (!layer_scr) continue;
3111
3112 5992096 int32_t newflag2 = -1;
3113
3114
2/2
✓ Branch 0 taken 11984192 times.
✓ Branch 1 taken 5992096 times.
17976288 for(int32_t iter=0; iter<2; ++iter)
3115 {
3116 11984192 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3117
3118
2/2
✓ Branch 0 taken 5992096 times.
✓ Branch 1 taken 5992096 times.
11984192 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3119
3120
4/4
✓ Branch 0 taken 159433 times.
✓ Branch 1 taken 11824759 times.
✓ Branch 2 taken 136546 times.
✓ Branch 3 taken 22887 times.
11984192 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3121 {
3122 22887 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3123 22887 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3124 22887 newflag2 = layer_scr->secretflag[checkflag-16+4];
3125 22887 }
3126 11984192 }
3127
3128
2/2
✓ Branch 0 taken 5969209 times.
✓ Branch 1 taken 22887 times.
5992096 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3129 5992096 }
3130 3315136 }
3131 3380784 }
3132
3133
2/2
✓ Branch 0 taken 508074 times.
✓ Branch 1 taken 19209 times.
527283 for(word i=0; i<c; i++) // FFCs
3134 {
3135
6/6
✓ Branch 0 taken 468053 times.
✓ Branch 1 taken 40021 times.
✓ Branch 2 taken 15497 times.
✓ Branch 3 taken 492577 times.
✓ Branch 4 taken 3657 times.
✓ Branch 5 taken 11840 times.
508074 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3136 {
3137 496234 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3138
3139 //No placed flags yet
3140
4/4
✓ Branch 0 taken 93 times.
✓ Branch 1 taken 496141 times.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 12 times.
496234 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3141 {
3142
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3143 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3144 else
3145 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3146 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3147 12 }
3148 496234 }
3149 527283 }
3150
3151 endhe:
3152
3153
1/2
✓ Branch 0 taken 19223 times.
✗ Branch 1 not taken.
19223 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3154 {
3155 if (from_active_screen)
3156 activated_timed_warp = true;
3157 scr->timedwarptics = 0;
3158 }
3159 19223 }
3160
3161 // x,y are world coordinates.
3162 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3163 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3164 13982906 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3165 {
3166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13982906 times.
13982906 if (!is_in_world_bounds(x, y)) return false;
3167
3168 13982906 bool found_cflag = false;
3169 13982906 bool found_nflag = false;
3170 13982906 bool single16 = false;
3171 13982906 rpos_t rpos = rpos_t::None;
3172
3173
2/2
✓ Branch 0 taken 13980804 times.
✓ Branch 1 taken 97868060 times.
111848864 for (int32_t layer = -1; layer < 6; layer++)
3174 {
3175
2/2
✓ Branch 0 taken 97865958 times.
✓ Branch 1 taken 2102 times.
97868060 if (MAPFLAG2(layer, x, y) == flag)
3176 {
3177 2102 found_nflag = true;
3178 2102 break;
3179 }
3180 97865958 }
3181
3182
2/2
✓ Branch 0 taken 13982517 times.
✓ Branch 1 taken 97878647 times.
111861164 for (int32_t layer = -1; layer < 6; layer++)
3183 {
3184
2/2
✓ Branch 0 taken 97878258 times.
✓ Branch 1 taken 389 times.
97878647 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3185 {
3186 389 found_cflag = true;
3187 389 break;
3188 }
3189 97878258 }
3190
3191
2/2
✓ Branch 0 taken 97880342 times.
✓ Branch 1 taken 13982906 times.
111863248 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3192 {
3193
2/2
✓ Branch 0 taken 97865628 times.
✓ Branch 1 taken 14714 times.
97880342 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3194 {
3195
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14602 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14714 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3196 {
3197 112 rpos = COMBOPOS_REGION(x, y);
3198 112 }
3199
3/4
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 14546 times.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
14602 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3200 {
3201 56 rpos = COMBOPOS_REGION(x, y);
3202 56 single16 = true;
3203 56 }
3204 14714 }
3205
3206
2/2
✓ Branch 0 taken 97877619 times.
✓ Branch 1 taken 2723 times.
97880342 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3207 {
3208
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 2468 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2723 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3209 {
3210 255 rpos = COMBOPOS_REGION(x, y);
3211 255 }
3212
3/4
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 2439 times.
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
2468 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3213 {
3214 29 rpos = COMBOPOS_REGION(x, y);
3215 29 single16 = true;
3216 29 }
3217 2723 }
3218 97880342 }
3219
3220 13982906 out_rpos = rpos;
3221 13982906 out_single16 = single16;
3222
4/4
✓ Branch 0 taken 13980804 times.
✓ Branch 1 taken 2102 times.
✓ Branch 2 taken 13980419 times.
✓ Branch 3 taken 385 times.
13982906 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3223 13982906 }
3224
3225 4604586 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3226 {
3227
8/8
✓ Branch 0 taken 4604346 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4602449 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4601929 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4600977 times.
4604586 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3228
3229 4600977 mapscr* scr = NULL;
3230 4600977 int32_t screen = -1;
3231 4600977 rpos_t trigger_rpos = rpos_t::None;
3232 4600977 bool single16 = false;
3233
3234 4600977 std::vector<std::pair<int, int>> coords;
3235
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x, y});
3236
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x + 15, y});
3237
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x, y + 15});
3238
1/2
✓ Branch 0 taken 4600977 times.
✗ Branch 1 not taken.
4600977 coords.push_back({x + 15, y + 15});
3239 4600977 std::vector<rpos_t> rposes_seen;
3240
2/2
✓ Branch 0 taken 4598479 times.
✓ Branch 1 taken 18398387 times.
87336590 for (auto [x, y] : coords)
3241 {
3242
2/4
✓ Branch 0 taken 18398387 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18398387 times.
✗ Branch 3 not taken.
36796774 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3243
2/2
✓ Branch 0 taken 18184458 times.
✓ Branch 1 taken 213929 times.
18398387 if (rpos == rpos_t::None)
3244 213929 continue;
3245
3246
4/6
✓ Branch 0 taken 18184458 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18184458 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 18184447 times.
36368916 if (MAPFFCOMBOFLAG(x, y) == flag)
3247 {
3248
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3249 11 break;
3250 }
3251
3252 18184447 bool seen = false;
3253
2/2
✓ Branch 0 taken 13982906 times.
✓ Branch 1 taken 22894140 times.
36877046 for (rpos_t r : rposes_seen)
3254 {
3255
2/2
✓ Branch 0 taken 18692599 times.
✓ Branch 1 taken 4201541 times.
22894140 if (r == rpos)
3256 {
3257 4201541 seen = true;
3258 4201541 break;
3259 }
3260 }
3261
2/2
✓ Branch 0 taken 13982906 times.
✓ Branch 1 taken 4201541 times.
18184447 if (seen)
3262 4201541 continue;
3263
3264
1/2
✓ Branch 0 taken 13982906 times.
✗ Branch 1 not taken.
13982906 rposes_seen.push_back(rpos);
3265
4/6
✓ Branch 0 taken 13982906 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13982906 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2487 times.
✓ Branch 5 taken 13980419 times.
27965812 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3266 {
3267
2/4
✓ Branch 0 taken 2487 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2487 times.
✗ Branch 3 not taken.
4974 screen = get_screen_for_world_xy(x, y);
3268 2487 break;
3269 }
3270 }
3271
3272
3/4
✓ Branch 0 taken 2498 times.
✓ Branch 1 taken 4598479 times.
✓ Branch 2 taken 2498 times.
✗ Branch 3 not taken.
4600977 if (screen != -1) scr = get_scr(screen);
3273
2/2
✓ Branch 0 taken 2498 times.
✓ Branch 1 taken 4598479 times.
4600977 if (!scr) return false;
3274
3275
2/2
✓ Branch 0 taken 2046 times.
✓ Branch 1 taken 452 times.
2498 if (trigger_rpos == rpos_t::None)
3276 {
3277 2046 checktrigger = true;
3278
1/2
✓ Branch 0 taken 2046 times.
✗ Branch 1 not taken.
2046 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3279 2046 }
3280 else
3281 {
3282 452 checktrigger = true;
3283
2/4
✓ Branch 0 taken 452 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 452 times.
✗ Branch 3 not taken.
452 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3284 }
3285
3286
1/2
✓ Branch 0 taken 2498 times.
✗ Branch 1 not taken.
2498 sfx(scr->secretsfx);
3287
3288
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 2477 times.
2498 if(scr->flags6&fTRIGGERFPERM)
3289 {
3290
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 int32_t flags_remaining = findtrigger(screen); //Normal flags
3291
3292
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 9 times.
21 if (flags_remaining)
3293 {
3294
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3295 12 setflag=false;
3296 12 }
3297
3298 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3299 // which case only the screen state for mSECRET may be set below.
3300
4/4
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 3 times.
21 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3301 {
3302
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3303 6 }
3304 21 }
3305
3306
5/6
✓ Branch 0 taken 2384 times.
✓ Branch 1 taken 114 times.
✓ Branch 2 taken 2384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1276 times.
2498 if (setflag && canPermSecret(cur_dmap, screen))
3307
2/2
✓ Branch 0 taken 813 times.
✓ Branch 1 taken 463 times.
2089 if(!(scr->flags5&fTEMPSECRETS))
3308
1/2
✓ Branch 0 taken 813 times.
✗ Branch 1 not taken.
813 setmapflag(scr, mSECRET);
3309
3310 2498 return true;
3311 4604586 }
3312
3313 15385298 void update_slopes()
3314 {
3315
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 15385298 times.
15527654 for (auto& p : slopes)
3316 {
3317 142356 slope_object& s = p.second;
3318 142356 s.updateslope(); //sets old x/y poses
3319 }
3320 15385298 }
3321
3322 14927851 void update_freeform_combos()
3323 {
3324 14927851 ffscript_engine(false);
3325
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14903679 times.
14927851 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3326 {
3327 14903679 int wrap_right = world_w + 32;
3328 14903679 int wrap_bottom = world_h + 32;
3329
3330 488485239 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3331 473581560 mapscr* scr = ffc_handle.scr;
3332 473581560 ffcdata& thisffc = *ffc_handle.ffc;
3333
3334 // Combo 0?
3335
2/2
✓ Branch 0 taken 47283383 times.
✓ Branch 1 taken 426298177 times.
473581560 if(thisffc.data==0)
3336 426298177 return;
3337
3338 // Changer?
3339
2/2
✓ Branch 0 taken 562821 times.
✓ Branch 1 taken 46720562 times.
47283383 if(thisffc.flags&ffc_changer)
3340 562821 return;
3341
3342 // Stationary?
3343
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 46710718 times.
46720562 if(thisffc.flags&ffc_stationary)
3344 9844 return;
3345
3346 // Frozen because Hero's holding up an item?
3347
3/4
✓ Branch 0 taken 157429 times.
✓ Branch 1 taken 46553289 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 157429 times.
46710718 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3348 157429 return;
3349
3350 // Check for changers
3351
2/2
✓ Branch 0 taken 31045254 times.
✓ Branch 1 taken 15508035 times.
46553289 if (thisffc.link==0)
3352 {
3353 446641803 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3354
2/2
✓ Branch 0 taken 15506398 times.
✓ Branch 1 taken 415627370 times.
431133768 if (ffc_handle.id == other_ffc_handle.id)
3355 15506398 return true;
3356
3357 415627370 ffcdata& otherffc = *other_ffc_handle.ffc;
3358 // Combo 0?
3359
2/2
✓ Branch 0 taken 147056016 times.
✓ Branch 1 taken 268571354 times.
415627370 if(otherffc.data==0)
3360 268571354 return true;
3361
3362 // Not a changer?
3363
2/2
✓ Branch 0 taken 142873987 times.
✓ Branch 1 taken 4182029 times.
147056016 if(!(otherffc.flags&ffc_changer))
3364 142873987 return true;
3365
3366 // Ignore this changer?
3367
4/4
✓ Branch 0 taken 564215 times.
✓ Branch 1 taken 3617814 times.
✓ Branch 2 taken 308097 times.
✓ Branch 3 taken 3309717 times.
4182029 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3368 872312 return true;
3369
3370
3/4
✓ Branch 0 taken 2870799 times.
✓ Branch 1 taken 438918 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3663 times.
3313380 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3371 ( // At exactly the same position,
3372
2/2
✓ Branch 0 taken 217547 times.
✓ Branch 1 taken 2653252 times.
2870799 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3373
2/2
✓ Branch 0 taken 2435705 times.
✓ Branch 1 taken 2653252 times.
217547 ||
3374 //or imprecision and close enough
3375
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5306504 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3376 )
3377 && //and...
3378
2/2
✓ Branch 0 taken 3663 times.
✓ Branch 1 taken 2870960 times.
2874623 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3379 {
3380 3663 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3381 3663 return false;
3382 }
3383
3384 2870960 return true;
3385 430082480 });
3386 15508035 }
3387
3388
2/2
✓ Branch 0 taken 31045254 times.
✓ Branch 1 taken 15508035 times.
46553289 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3389
4/4
✓ Branch 0 taken 15508035 times.
✓ Branch 1 taken 31045254 times.
✓ Branch 2 taken 15430742 times.
✓ Branch 3 taken 15614512 times.
46553289 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3390 {
3391
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 15431903 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
15614512 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3392 {
3393 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3394 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3395 97278 thisffc.x += linked_ffc->vx;
3396 97278 thisffc.y += linked_ffc->vy;
3397 97278 }
3398 else
3399 {
3400 15517234 thisffc.prev_changer_x = thisffc.x.getZLong();
3401 15517234 thisffc.prev_changer_y = thisffc.y.getZLong();
3402 15517234 thisffc.x += thisffc.vx;
3403 15517234 thisffc.y += thisffc.vy;
3404 15517234 thisffc.vx += thisffc.ax;
3405 15517234 thisffc.vy += thisffc.ay;
3406
3407
3408
2/2
✓ Branch 0 taken 1192049 times.
✓ Branch 1 taken 14325185 times.
15517234 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3409 {
3410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vx>128) thisffc.vx=128;
3411
3412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vx<-128) thisffc.vx=-128;
3413
3414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vy>128) thisffc.vy=128;
3415
3416
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14325185 times.
14325185 if(thisffc.vy<-128) thisffc.vy=-128;
3417 14325185 }
3418 }
3419 15614512 }
3420 else
3421 {
3422
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76132 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
30938777 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3423 76132 thisffc.delay--;
3424 }
3425
3426 // Check if the FFC's off the side of the screen
3427
3428 // Left
3429
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 15681356 times.
15691805 if(thisffc.x<-32)
3430 {
3431
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3432 {
3433 253 thisffc.x = wrap_right+(thisffc.x+32);
3434 253 thisffc.solid_update(false);
3435 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3436 // Re-enable previous changer
3437 253 thisffc.changer_x = -1000;
3438 253 thisffc.changer_y = -1000;
3439 253 }
3440
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3441 {
3442 69 zc_ffc_set(thisffc, 0);
3443 69 thisffc.flags&=~ffc_carryover;
3444 69 }
3445 10449 }
3446 // Right
3447
2/2
✓ Branch 0 taken 15681175 times.
✓ Branch 1 taken 181 times.
15681356 else if(thisffc.x>=wrap_right)
3448 {
3449
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3450 {
3451 128 thisffc.x = thisffc.x-wrap_right-32;
3452 128 thisffc.solid_update(false);
3453 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3454 128 thisffc.changer_x = -1000;
3455 128 thisffc.changer_y = -1000;
3456 128 }
3457 else
3458 {
3459 53 zc_ffc_set(thisffc, 0);
3460 53 thisffc.flags&=~ffc_carryover;
3461 }
3462 181 }
3463
3464 // Top
3465
2/2
✓ Branch 0 taken 25806 times.
✓ Branch 1 taken 15665999 times.
15691805 if(thisffc.y<-32)
3466 {
3467
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25798 times.
25806 if(scr->flags6&fWRAPAROUNDFF)
3468 {
3469 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3470 8 thisffc.solid_update(false);
3471 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3472 8 thisffc.changer_x = -1000;
3473 8 thisffc.changer_y = -1000;
3474 8 }
3475
2/2
✓ Branch 0 taken 25481 times.
✓ Branch 1 taken 317 times.
25798 else if(thisffc.y<-64)
3476 {
3477 317 zc_ffc_set(thisffc, 0);
3478 317 thisffc.flags&=~ffc_carryover;
3479 317 }
3480 25806 }
3481 // Bottom
3482
2/2
✓ Branch 0 taken 15665131 times.
✓ Branch 1 taken 868 times.
15665999 else if(thisffc.y>=wrap_bottom)
3483 {
3484
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 115 times.
868 if(scr->flags6&fWRAPAROUNDFF)
3485 {
3486 753 thisffc.y = thisffc.y-wrap_bottom-32;
3487 753 thisffc.solid_update(false);
3488 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3489 753 thisffc.changer_x = -1000;
3490 753 thisffc.changer_y = -1000;
3491 753 }
3492 else
3493 {
3494 115 zc_ffc_set(thisffc, 0);
3495 115 thisffc.flags&=~ffc_carryover;
3496 }
3497 868 }
3498 15691805 thisffc.solid_update();
3499 442720076 });
3500 14903679 }
3501 14927851 }
3502
3503 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3504 {
3505 for(int q = 0; q < 7; ++q)
3506 {
3507 if(layers&(1<<q)) //if layer is to be checked
3508 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3509 return true;
3510 }
3511 return false;
3512 }
3513
3514 231 optional<int> nextscr(int screen, int dir)
3515 {
3516 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3517
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3518 462 return (m<<7) + s;
3519 231 }
3520
3521 1064 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3522 {
3523 1064 int32_t map = cur_map;
3524
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1064 times.
1064 int32_t screen = screenscrolling ? scrolling_hero_screen : Hero.current_screen;
3525 1064 return nextscr2(map, screen, dir);
3526 }
3527
3528 5582 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3529 {
3530 5582 screen = screen_index_direction(screen, (direction)dir);
3531
3532 // need to check for screens on other maps, 's' not valid, etc.
3533 5582 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3534
3535 // Fun fact: when a scrolling warp is triggered, this function
3536 // is never even called! - Saf
3537
2/2
✓ Branch 0 taken 3330 times.
✓ Branch 1 taken 2252 times.
6126 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3538 {
3539
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 527 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 697 times.
2252 switch(dir)
3540 {
3541 case up:
3542
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3543
3544 83 break;
3545
3546 case down:
3547
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 448 times.
527 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3548
3549 79 break;
3550
3551 case left:
3552
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 337 times.
546 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3553
3554 209 break;
3555
3556 case right:
3557
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 524 times.
697 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3558
3559 173 break;
3560 }
3561
3562 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3563 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3564 544 }
3565
3566 nowarp:
3567
4/4
✓ Branch 0 taken 5518 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5406 times.
5582 if(screen<0||screen>=128)
3568 176 return {-1, -1};
3569
3570 5406 return {map, screen};
3571 5582 }
3572
3573 403 optional<int> nextscr_mi(int mi, int dir)
3574 {
3575 403 int map = mi/MAPSCRSNORMAL;
3576 403 int screen = mi%MAPSCRSNORMAL;
3577 403 auto [m, s] = nextscr2(map, screen, dir);
3578
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3579 804 return (m<<7) + s;
3580 403 }
3581
3582 2297 void bombdoor(int32_t x,int32_t y)
3583 {
3584
2/2
✓ Branch 0 taken 2276 times.
✓ Branch 1 taken 21 times.
2297 if (!is_in_world_bounds(x, y))
3585 21 return;
3586
3587 2276 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3588 2276 mapscr* scr = rpos_handle.scr;
3589 2276 int screen = scr->screen;
3590 3084 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3591 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3592
3593
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2197 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2276 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3594 {
3595 69 scr->door[0]=dBOMBED;
3596 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3597 69 setmapflag(scr, mDOOR_UP);
3598 69 markBmap(-1, screen);
3599
3600
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3601 {
3602 69 setmapflag_mi(*v, mDOOR_DOWN);
3603 69 markBmap(-1,*v-(get_currdmap()<<7));
3604 69 }
3605 69 }
3606
3607
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2227 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2276 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3608 {
3609 39 scr->door[1]=dBOMBED;
3610 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3611 39 setmapflag(scr, mDOOR_DOWN);
3612 39 markBmap(-1, rpos_handle.screen);
3613
3614
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3615 {
3616 39 setmapflag_mi(*v, mDOOR_UP);
3617 39 markBmap(-1,*v-(get_currdmap()<<7));
3618 39 }
3619 39 }
3620
3621
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2209 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2276 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3622 {
3623 51 scr->door[2]=dBOMBED;
3624 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3625 51 setmapflag(scr, mDOOR_LEFT);
3626 51 markBmap(-1, rpos_handle.screen);
3627
3628
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3629 {
3630 51 setmapflag_mi(*v, mDOOR_RIGHT);
3631 51 markBmap(-1,*v-(get_currdmap()<<7));
3632 51 }
3633 51 }
3634
3635
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2190 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2276 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3636 {
3637 72 scr->door[3]=dBOMBED;
3638 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3639 72 setmapflag(scr, mDOOR_RIGHT);
3640 72 markBmap(-1, rpos_handle.screen);
3641
3642
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3643 {
3644 72 setmapflag_mi(*v, mDOOR_LEFT);
3645 72 markBmap(-1,*v-(get_currdmap()<<7));
3646 72 }
3647 72 }
3648 2297 }
3649
3650 7118839665 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3651 bool over, bool transp)
3652 {
3653 7118839665 auto& cmb = combobuf[cid];
3654
2/2
✓ Branch 0 taken 93673 times.
✓ Branch 1 taken 7118745992 times.
7118839665 if(cmb.animflags & AF_EDITOR_ONLY)
3655 93673 return;
3656
2/2
✓ Branch 0 taken 3924435462 times.
✓ Branch 1 taken 3194310530 times.
7118745992 if(over)
3657 {
3658
2/2
✓ Branch 0 taken 841117 times.
✓ Branch 1 taken 3923594345 times.
3924435462 if(cmb.animflags & AF_TRANSPARENT)
3659 841117 transp = !transp;
3660
2/2
✓ Branch 0 taken 328615081 times.
✓ Branch 1 taken 3595820381 times.
3924435462 if(transp)
3661 328615081 overcombotranslucent(dest, x, y, cid, cset, 128);
3662 3595820381 else overcombo(dest, x, y, cid, cset);
3663 3924435462 }
3664 3194310530 else putcombo(dest, x, y, cid, cset);
3665 7118839665 }
3666 7118848113 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3667 int32_t cset, byte layer, bool over, bool transp)
3668 {
3669
2/2
✓ Branch 0 taken 847534117 times.
✓ Branch 1 taken 6271313996 times.
7118848113 if (rpos != rpos_t::None)
3670 {
3671 6271313996 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3672
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 6270564472 times.
6271313996 if (plrpos != rpos_t::None)
3673 {
3674 6270564472 bool dosw = false;
3675
4/4
✓ Branch 0 taken 67998 times.
✓ Branch 1 taken 6270496474 times.
✓ Branch 2 taken 59550 times.
✓ Branch 3 taken 8448 times.
6270564472 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3676 {
3677
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3678 {
3679 draw_cmb(dest, x, y,
3680 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3681 }
3682 8448 dosw = true;
3683 8448 }
3684
4/4
✓ Branch 0 taken 35594992 times.
✓ Branch 1 taken 6234961032 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 35586544 times.
6270556024 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3685 {
3686 8448 dosw = true;
3687 8448 }
3688
2/2
✓ Branch 0 taken 6270547576 times.
✓ Branch 1 taken 16896 times.
6270564472 if (dosw)
3689 {
3690
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3691 {
3692 default: case swPOOF:
3693 break; //Nothing special here
3694 case swFLICKER:
3695 {
3696
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3697 8448 break; //Drawn this frame
3698 8448 return; //Not drawn this frame
3699 }
3700 case swRISE:
3701 {
3702 //Draw rising up
3703 y -= 8-(abs(Hero.switchhookclk-32)/4);
3704 break;
3705 }
3706 }
3707 8448 }
3708 6270556024 }
3709 6271305548 }
3710
3711 7118839665 draw_cmb(dest, x, y, cid, cset, over, transp);
3712 7118848113 }
3713
3714 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3715 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3716 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3717 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3718 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3719 //
3720 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3721 //
3722 // -16 < comboPositionX*16 + x < bitmapWidth
3723 // -16 < comboPositionY*16 + y < bitmapHeight
3724 //
3725 // The following start/end values are derived directly from the above.
3726 //
3727 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3728 44029327 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3729 {
3730 // if (bmp->clip)
3731 // {
3732 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3733 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3734 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3735 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3736 // return;
3737 // }
3738
3739
2/2
✓ Branch 0 taken 2404962 times.
✓ Branch 1 taken 41624365 times.
44029327 start_x = MAX(0, ceil((-15 - x) / 16.0));
3740
2/2
✓ Branch 0 taken 2412938 times.
✓ Branch 1 taken 41616389 times.
44029327 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3741
2/2
✓ Branch 0 taken 42490778 times.
✓ Branch 1 taken 1538549 times.
44029327 start_y = MAX(0, ceil((-15 - y) / 16.0));
3742
2/2
✓ Branch 0 taken 1874535 times.
✓ Branch 1 taken 42154792 times.
44029327 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3743 44029327 }
3744
3745 195665656 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3746 {
3747
1/2
✓ Branch 0 taken 195665656 times.
✗ Branch 1 not taken.
195665656 if(!show_ffcs) return;
3748 195665656 mapscr* scr = screen_handle.scr;
3749 195665656 mapscr* base_scr = screen_handle.base_scr;
3750
3751 195665656 y += playing_field_offset;
3752
3753 195665656 bool is_overhead = layer == -1000;
3754
2/2
✓ Branch 0 taken 53234780 times.
✓ Branch 1 taken 142430876 times.
195665656 bool is_bg_layer = layer < 0 && !is_overhead;
3755
2/2
✓ Branch 0 taken 35525190 times.
✓ Branch 1 taken 160140466 times.
195665656 int real_layer = is_bg_layer ? abs(layer) : layer;
3756
2/2
✓ Branch 0 taken 195665656 times.
✓ Branch 1 taken 5610067558 times.
5805733214 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3757 {
3758
2/2
✓ Branch 0 taken 217455144 times.
✓ Branch 1 taken 5392612414 times.
5610067558 if (base_scr->ffcs[i].data == 0)
3759 5392612414 continue;
3760
3/4
✓ Branch 0 taken 39536116 times.
✓ Branch 1 taken 177919028 times.
✓ Branch 2 taken 39536116 times.
✗ Branch 3 not taken.
217455144 if (is_bg_layer && base_scr->ffcs[i].layer == layer)
3761 ; // ffc is set negative, skip bg layer flag checks
3762 else
3763 {
3764
4/4
✓ Branch 0 taken 39536089 times.
✓ Branch 1 taken 177919055 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 19768031 times.
217455144 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3765 19768031 continue;
3766
4/4
✓ Branch 0 taken 39535883 times.
✓ Branch 1 taken 158151230 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 19767825 times.
197687113 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3767 19767825 continue;
3768
4/4
✓ Branch 0 taken 158156192 times.
✓ Branch 1 taken 19763096 times.
✓ Branch 2 taken 19768058 times.
✓ Branch 3 taken 138388134 times.
177919288 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3769 138388134 continue;
3770 }
3771
3772
6/6
✓ Branch 0 taken 3311080 times.
✓ Branch 1 taken 36220074 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3305970 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
39531154 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3773 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3774
3775 39528670 base_scr->ffcs[i].draw_ffc(bmp, x, y, is_overhead);
3776 39528670 }
3777 195665656 }
3778 177474124 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3779 {
3780
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 177474124 times.
177474124 if(!show_ffcs) return;
3781 359873190 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3782 182399066 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3783 182399066 do_ffc_layer(bmp, layer, handle, 0, 0);
3784 182399066 });
3785 177474124 }
3786 110478586 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3787 {
3788 110478586 mapscr* scr = screen_handle.scr;
3789 110478586 mapscr* base_scr = screen_handle.base_scr;
3790
3791
4/4
✓ Branch 0 taken 69322574 times.
✓ Branch 1 taken 41156012 times.
✓ Branch 2 taken 41156012 times.
✓ Branch 3 taken 110478586 times.
110478586 if (type == -3 || type == -4)
3792 {
3793 82312024 y += playing_field_offset;
3794
3795
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
82312024 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3796 {
3797 if (base_scr->ffcs[i].data == 0)
3798 continue;
3799
3800 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3801 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3802
3803 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3804 }
3805 return;
3806 }
3807
3808 110478586 x -= viewport.x;
3809 110478586 y -= viewport.y - playing_field_offset;
3810
3811 110478586 bool over = true, transp = false;
3812 110478586 int layer = screen_handle.layer;
3813
3814
7/8
✓ Branch 0 taken 86212000 times.
✓ Branch 1 taken 24266586 times.
✓ Branch 2 taken 15025887 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 62897037 times.
✓ Branch 5 taken 23314963 times.
✓ Branch 6 taken 3907230 times.
✓ Branch 7 taken 5333469 times.
110478586 switch(type ? type : layer)
3815 {
3816 case -2: //push blocks
3817
2/2
✓ Branch 0 taken 21741025 times.
✓ Branch 1 taken 41156012 times.
62897037 if (scr)
3818 {
3819
2/2
✓ Branch 0 taken 3826420400 times.
✓ Branch 1 taken 62081685 times.
3862834845 for(int32_t i=0; i<176; i++)
3820 {
3821 3826420400 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3822
3823
10/10
✓ Branch 0 taken 3826250056 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3824772851 times.
✓ Branch 3 taken 1477205 times.
✓ Branch 4 taken 3824139612 times.
✓ Branch 5 taken 633239 times.
✓ Branch 6 taken 53394531 times.
✓ Branch 7 taken 3770745081 times.
✓ Branch 8 taken 100280201 times.
✓ Branch 9 taken 57521370 times.
3870011913 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3824
6/8
✓ Branch 0 taken 3821256963 times.
✓ Branch 1 taken 50511882 times.
✓ Branch 2 taken 3821256963 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3821256963 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 43591513 times.
✓ Branch 7 taken 3777665450 times.
3824139612 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3825 {
3826
4/4
✓ Branch 0 taken 5124570 times.
✓ Branch 1 taken 782430 times.
✓ Branch 2 taken 3849 times.
✓ Branch 3 taken 5120721 times.
206467402 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3827 5907000 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3828 5907000 }
3829 3841093820 }
3830 62081685 }
3831 103237697 return;
3832
3833 case -1: //over combo
3834
1/2
✓ Branch 0 taken 23314963 times.
✗ Branch 1 not taken.
23314963 if (scr)
3835 {
3836
2/2
✓ Branch 0 taken 4103433488 times.
✓ Branch 1 taken 23314963 times.
4126748451 for(int32_t i=0; i<176; i++)
3837 {
3838
2/2
✓ Branch 0 taken 4084103568 times.
✓ Branch 1 taken 19329920 times.
4103433488 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3839 {
3840
4/4
✓ Branch 0 taken 15574819 times.
✓ Branch 1 taken 3755101 times.
✓ Branch 2 taken 22336 times.
✓ Branch 3 taken 15552483 times.
19329920 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3841 19329920 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3842 19329920 }
3843 4103433488 }
3844 23314963 }
3845 23314963 return;
3846
3847 case 1:
3848 case 4:
3849 case 5:
3850 case 6:
3851
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15025887 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
15025887 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3852 {
3853
1/2
✓ Branch 0 taken 15025887 times.
✗ Branch 1 not taken.
15025887 if (scr)
3854 {
3855
2/2
✓ Branch 0 taken 13331185 times.
✓ Branch 1 taken 1694702 times.
15025887 if(base_scr->layeropacity[layer-1]!=255)
3856 1694702 transp = true;
3857 15025887 break;
3858 }
3859 }
3860 return;
3861
3862 case 2:
3863
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3907230 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3907230 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3864 {
3865
1/2
✓ Branch 0 taken 3907230 times.
✗ Branch 1 not taken.
3907230 if (scr)
3866 {
3867
2/2
✓ Branch 0 taken 3670944 times.
✓ Branch 1 taken 236286 times.
3907230 if(base_scr->layeropacity[layer-1]!=255)
3868 236286 transp = true;
3869
3870
2/2
✓ Branch 0 taken 3759775 times.
✓ Branch 1 taken 147455 times.
3907230 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3871 147455 over = false;
3872
3873 3907230 break;
3874 }
3875 }
3876 return;
3877
3878 case 3:
3879
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5333469 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
5333469 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3880 {
3881
1/2
✓ Branch 0 taken 5333469 times.
✗ Branch 1 not taken.
5333469 if (scr)
3882 {
3883
2/2
✓ Branch 0 taken 5258193 times.
✓ Branch 1 taken 75276 times.
5333469 if(base_scr->layeropacity[layer-1]!=255)
3884 75276 transp = true;
3885
3886
2/2
✓ Branch 0 taken 36654 times.
✓ Branch 1 taken 237618 times.
5333469 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3887
2/2
✓ Branch 0 taken 274272 times.
✓ Branch 1 taken 5059197 times.
5333469 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3888 237618 over = false;
3889
3890 5333469 break;
3891 }
3892 }
3893 return;
3894 }
3895
3896 int start_x, end_x, start_y, end_y;
3897 24266586 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3898
2/2
✓ Branch 0 taken 24266586 times.
✓ Branch 1 taken 257467292 times.
281733878 for (int cy = start_y; cy < end_y; cy++)
3899 {
3900
2/2
✓ Branch 0 taken 3897791767 times.
✓ Branch 1 taken 257467292 times.
4155259059 for (int cx = start_x; cx < end_x; cx++)
3901 {
3902 3897791767 int i = cx + cy*16;
3903
4/4
✓ Branch 0 taken 3440940732 times.
✓ Branch 1 taken 456851035 times.
✓ Branch 2 taken 11831072 times.
✓ Branch 3 taken 3429109660 times.
3897791767 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3904 3897791767 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3905 3897791767 }
3906 257467292 }
3907 69322574 }
3908
3909 279461725 bool lenscheck(mapscr* scr, int layer)
3910 {
3911
4/4
✓ Branch 0 taken 279285153 times.
✓ Branch 1 taken 176572 times.
✓ Branch 2 taken 176572 times.
✓ Branch 3 taken 279461725 times.
279461725 if(layer < 0 || layer > 6) return true;
3912
2/2
✓ Branch 0 taken 259624545 times.
✓ Branch 1 taken 19837180 times.
279461725 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3913 {
3914
2/2
✓ Branch 0 taken 209738725 times.
✓ Branch 1 taken 49885820 times.
259624545 if(!layer) return true;
3915
8/8
✓ Branch 0 taken 34927477 times.
✓ Branch 1 taken 174811248 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34668507 times.
✓ Branch 4 taken 146134 times.
✓ Branch 5 taken 259680 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34488105 times.
209738725 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3916 586216 return false;
3917 209299353 }
3918 else
3919 {
3920
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 19837180 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 19837180 times.
19837180 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3921 return false;
3922 }
3923 229136533 return true;
3924 279285153 }
3925
3926 165109913 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3927 {
3928 165109913 bool showlayer = true;
3929 165109913 mapscr* base_scr = screen_handle.base_scr;
3930 165109913 int layer = screen_handle.layer;
3931
2/2
✓ Branch 0 taken 46557749 times.
✓ Branch 1 taken 118552164 times.
165109913 int target = type ? type : layer;
3932
3/4
✓ Branch 0 taken 118552164 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22470191 times.
✓ Branch 3 taken 24087558 times.
165109913 switch(target)
3933 {
3934 case -2:
3935
1/2
✓ Branch 0 taken 22470191 times.
✗ Branch 1 not taken.
22470191 if(!show_layer_push)
3936 showlayer = false;
3937 22470191 break;
3938
3939 case -1:
3940
1/2
✓ Branch 0 taken 24087558 times.
✗ Branch 1 not taken.
24087558 if(!show_layer_over)
3941 showlayer = false;
3942 24087558 break;
3943
3944 case 1: case 2: case 3:
3945 case 4: case 5: case 6:
3946 118552164 showlayer = show_layers[target];
3947 118552164 break;
3948 }
3949
3950
2/2
✓ Branch 0 taken 46557749 times.
✓ Branch 1 taken 118552164 times.
165109913 if(!type)
3951 {
3952
2/2
✓ Branch 0 taken 118415966 times.
✓ Branch 1 taken 136198 times.
118552164 if(!lenscheck(base_scr,layer))
3953 136198 showlayer = false;
3954 118552164 }
3955
3956
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 164973715 times.
165109913 if(showlayer)
3957 {
3958
6/6
✓ Branch 0 taken 69414522 times.
✓ Branch 1 taken 95559193 times.
✓ Branch 2 taken 24358534 times.
✓ Branch 3 taken 45055988 times.
✓ Branch 4 taken 91948 times.
✓ Branch 5 taken 24266586 times.
164973715 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3959 {
3960 69322574 do_scrolling_layer(bmp, type, screen_handle, x, y);
3961
4/4
✓ Branch 0 taken 24266586 times.
✓ Branch 1 taken 45055988 times.
✓ Branch 2 taken 22269756 times.
✓ Branch 3 taken 1996830 times.
69322574 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3962
2/2
✓ Branch 0 taken 1996254 times.
✓ Branch 1 taken 576 times.
1997406 if(mblock2.draw(bmp,layer))
3963 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3964 69322574 }
3965 164973715 }
3966 165109913 }
3967
3968 107006542 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3969 {
3970 107006542 bool showlayer = true;
3971
3972
2/4
✓ Branch 0 taken 107006542 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 107006542 times.
107006542 if(layer >= 0 && layer <= 6)
3973 {
3974 107006542 showlayer = show_layers[layer];
3975
3976
2/2
✓ Branch 0 taken 106879940 times.
✓ Branch 1 taken 126602 times.
107006542 if(!lenscheck(origin_scr,layer))
3977 126602 showlayer = false;
3978 107006542 }
3979
3980
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 106879940 times.
107006542 if (showlayer)
3981 106879940 do_primitives(bmp, layer);
3982 107006542 }
3983
3984 // Called by do_walkflags
3985 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3986 {
3987 newcombo const &c = combobuf[cmbdat];
3988
3989 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
3990
3991 int32_t xx = x-xofs;
3992 int32_t yy = y+playing_field_offset-yofs;
3993
3994 int32_t bridgedetected = 0;
3995
3996 for(int32_t i=0; i<4; i++)
3997 {
3998 int32_t tx=((i&2)<<2)+xx - viewport.x;
3999 int32_t ty=((i&1)<<3)+yy - viewport.y;
4000 int32_t tx2=((i&2)<<2)+x - viewport.x;
4001 int32_t ty2=((i&1)<<3)+y - viewport.y;
4002 for (int32_t j = lyr-1; j <= 1; j++)
4003 {
4004 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4005 {
4006 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
4007 {
4008 bridgedetected |= (1<<i);
4009 }
4010 }
4011 else
4012 {
4013 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
4014 {
4015 bridgedetected |= (1<<i);
4016 }
4017 }
4018 }
4019 if ((bridgedetected & (1<<i)))
4020 {
4021 if (i >= 3) break;
4022 else continue;
4023 }
4024 bool doladdercheck = true;
4025
4026 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4027 {
4028 for(int32_t k=0; k<8; k+=2)
4029 for(int32_t j=0; j<8; j+=2)
4030 if(((k+j)/2)%2)
4031 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
4032 }
4033 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4034 {
4035 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4036 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4037 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
4038 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
4039 }
4040
4041 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4042 {
4043 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4044 {
4045 for(int32_t k=0; k<8; k+=2)
4046 for(int32_t j=0; j<8; j+=2)
4047 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
4048 }
4049 else
4050 {
4051 int32_t color = makecol(178,36,36);
4052
4053 if(isstepable(cmbdat)&& (!doladdercheck))
4054 color=makecol(165,105,8);
4055 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4056 color=makecol(170,170,170);
4057
4058 rectfill(dest,tx,ty,tx+7,ty+7,color);
4059 }
4060 }
4061 }
4062
4063 // Draw damage combos
4064 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
4065 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
4066 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
4067
4068 if(dmg)
4069 {
4070 int32_t color = makecol(255,255,0);
4071 if (bridgedetected <= 0)
4072 {
4073 for(int32_t k=0; k<16; k+=2)
4074 for(int32_t j=0; j<16; j+=2)
4075 if(((k+j)/2)%2)
4076 {
4077 int32_t x0 = x - viewport.x;
4078 int32_t y0 = y - viewport.y;
4079 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4080 }
4081 }
4082 else
4083 {
4084 for(int32_t i=0; i<4; i++)
4085 {
4086 if (!(bridgedetected & (1<<i)))
4087 {
4088 int32_t tx=((i&2)<<2)+x - viewport.x;
4089 int32_t ty=((i&1)<<3)+y - viewport.y;
4090 for(int32_t k=0; k<8; k+=2)
4091 for(int32_t j=0; j<8; j+=2)
4092 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4093 }
4094 }
4095 }
4096 }
4097 }
4098 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4099 {
4100 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4101 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4102 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4103 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4104 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4105 newcombo const &c = combobuf[cmbdat];
4106
4107 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4108
4109 int32_t xx = x-viewport.x;
4110 int32_t yy = y+playing_field_offset-viewport.y;
4111
4112 int32_t bridgedetected = 0;
4113
4114 // Draw damage combos
4115 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4116
4117 for(int32_t i=0; i<4; i++)
4118 {
4119 int32_t tx=((i&2)<<2)+xx;
4120 int32_t ty=((i&1)<<3)+yy;
4121 int32_t tx2=((i&2)<<2)+x;
4122 int32_t ty2=((i&1)<<3)+y;
4123 for (int32_t m = lyr-1; m <= 1; m++)
4124 {
4125 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4126 {
4127 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4128 {
4129 bridgedetected |= (1<<i);
4130 }
4131 }
4132 else
4133 {
4134 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4135 {
4136 bridgedetected |= (1<<i);
4137 }
4138 }
4139 }
4140 if ((bridgedetected & (1<<i)))
4141 continue;
4142 bool doladdercheck = true;
4143
4144 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4145 {
4146 for(int32_t k=0; k<8; k+=2)
4147 for(int32_t j=0; j<8; j+=2)
4148 if(((k+j)/2)%2)
4149 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4150 }
4151 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4152 {
4153 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4154 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4155 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4156 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4157 }
4158
4159 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4160 {
4161 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4162 {
4163 for(int32_t k=0; k<8; k+=2)
4164 for(int32_t j=0; j<8; j+=2)
4165 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4166 }
4167 else
4168 {
4169 ALLEGRO_COLOR* color = &col_solid;
4170
4171 if(isstepable(cmbdat)&& (!doladdercheck))
4172 color=&col_stepable;
4173 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4174 color=&col_lhook;
4175
4176 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4177 }
4178 }
4179
4180 if(dmg)
4181 {
4182 for(int32_t k=0; k<8; k+=2)
4183 for(int32_t j=0; j<8; j+=2)
4184 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4185 }
4186 }
4187 }
4188
4189 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4190 {
4191 newcombo const &c = combobuf[cmbdat];
4192
4193 int32_t xx = x-xofs-viewport.x;
4194 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4195
4196 for(int32_t i=0; i<4; i++)
4197 {
4198 int32_t tx=((i&2)<<2)+xx;
4199 int32_t ty=((i&1)<<3)+yy;
4200
4201 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4202 {
4203 int32_t color = vc(10);
4204
4205 rectfill(dest,tx,ty,tx+7,ty+7,color);
4206 }
4207 }
4208 }
4209 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4210 {
4211 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4212 newcombo const &c = combobuf[cmbdat];
4213
4214 int32_t xx = x-viewport.x;
4215 int32_t yy = y+playing_field_offset-viewport.y;
4216
4217 for(int32_t i=0; i<4; i++)
4218 {
4219 int32_t tx=((i&2)<<2)+xx;
4220 int32_t ty=((i&1)<<3)+yy;
4221
4222 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4223 {
4224 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4225 }
4226 }
4227 }
4228
4229 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4230 {
4231 for(auto cx = 0; cx < 256; cx += 16)
4232 {
4233 for(auto cy = 0; cy < 176; cy += 16)
4234 {
4235 if(isSVLadder(cx,cy))
4236 {
4237 auto nx = cx+x, ny = cy+y;
4238 if(cy && !isSVLadder(cx,cy-16))
4239 line(dest,nx,ny,nx+15,ny,c);
4240 rectfill(dest,nx,ny,nx+3,ny+15,c);
4241 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4242 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4243 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4244 }
4245 else if(isSVPlatform(cx,cy))
4246 {
4247 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4248 }
4249 }
4250 }
4251 }
4252 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4253 {
4254 for(auto cx = 0; cx < 256; cx += 16)
4255 {
4256 for(auto cy = 0; cy < 176; cy += 16)
4257 {
4258 if(isSVLadder(cx,cy))
4259 {
4260 auto nx = cx+x, ny = cy+y;
4261 if(cy && !isSVLadder(cx,cy-16))
4262 al_draw_line(nx,ny,nx+15,ny,c,1);
4263 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4264 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4265 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4266 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4267 }
4268 else if(isSVPlatform(cx,cy))
4269 {
4270 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4271 }
4272 }
4273 }
4274 }
4275
4276 // Walkflags L4 cheat
4277 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4278 {
4279 if (!show_walkflags)
4280 return;
4281
4282 start_info_bmp();
4283
4284 mapscr* scr = screen_handles[0].scr;
4285 for(int32_t i=0; i<176; i++)
4286 {
4287 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4288 }
4289
4290 for(int32_t k=0; k<2; k++)
4291 {
4292 scr = screen_handles[k + 1].scr;
4293
4294 if (scr)
4295 {
4296 for(int32_t i=0; i<176; i++)
4297 {
4298 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4299 }
4300 }
4301 }
4302
4303 end_info_bmp();
4304 }
4305
4306 void do_walkflags(int32_t x, int32_t y)
4307 {
4308 if (!show_walkflags)
4309 return;
4310
4311 x += -viewport.x;
4312 y += playing_field_offset - viewport.y;
4313
4314 start_info_bmp();
4315
4316 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4317 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4318 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4319
4320 end_info_bmp();
4321 }
4322
4323 // Effectflags L4 cheat
4324 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4325 {
4326 if(show_effectflags)
4327 {
4328 start_info_bmp();
4329
4330 for(int32_t i=0; i<176; i++)
4331 {
4332 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4333 }
4334
4335 end_info_bmp();
4336 }
4337 }
4338
4339 400489 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4340 {
4341 400489 int map = scr->map;
4342 400489 int screen = scr->screen;
4343
4344
2/2
✓ Branch 0 taken 2803423 times.
✓ Branch 1 taken 400489 times.
3203912 for(int32_t lyr = 0; lyr < 7; ++lyr)
4345 {
4346 2803423 mapscr* scr = get_scr_layer(map, screen, lyr);
4347
2/2
✓ Branch 0 taken 1829718 times.
✓ Branch 1 taken 973705 times.
2803423 if (!scr->is_valid()) continue;
4348
4349
2/2
✓ Branch 0 taken 322030368 times.
✓ Branch 1 taken 1829718 times.
323860086 for(int32_t q = 0; q < 176; ++q)
4350 {
4351 322030368 newcombo const& cmb = combobuf[scr->data[q]];
4352
2/2
✓ Branch 0 taken 320498295 times.
✓ Branch 1 taken 1532073 times.
322030368 if(cmb.type == cTORCH)
4353 {
4354 1532073 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4355 1532073 }
4356 322030368 }
4357 1829718 }
4358 400489 }
4359
4360 400489 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4361 {
4362 400489 word c = scr->numFFC();
4363
2/2
✓ Branch 0 taken 704965 times.
✓ Branch 1 taken 400489 times.
1105454 for(int q = 0; q < c; ++q)
4364 {
4365 704965 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4366
2/2
✓ Branch 0 taken 690157 times.
✓ Branch 1 taken 14808 times.
704965 if(cmb.type == cTORCH)
4367 {
4368 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4369 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4370 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4371 14808 }
4372 704965 }
4373 400489 }
4374
4375 struct nearby_screen_t
4376 {
4377 int screen;
4378 int offx;
4379 int offy;
4380 screen_handles_t screen_handles;
4381 };
4382 typedef std::vector<nearby_screen_t> nearby_screens_t;
4383
4384 16076884 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4385 {
4386 16076884 nearby_screens_t nearby_screens;
4387
4388 16076884 mapscr* base_scr = origin_scr;
4389
1/2
✓ Branch 0 taken 16076884 times.
✗ Branch 1 not taken.
16076884 auto& nearby_screen = nearby_screens.emplace_back();
4390 16076884 nearby_screen.screen = cur_screen;
4391
1/2
✓ Branch 0 taken 16076884 times.
✗ Branch 1 not taken.
16076884 nearby_screen.screen_handles = create_screen_handles(base_scr);
4392
4393 16076884 return nearby_screens;
4394
1/2
✓ Branch 0 taken 16076884 times.
✗ Branch 1 not taken.
16076884 }
4395
4396 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4397 {
4398 48296 nearby_screens_t nearby_screens;
4399
4400
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4401
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4402
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4403
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4404
4405
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4406
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4407
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4408
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4409
4410
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4411 {
4412
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4413 {
4414 169672 int screen = cur_screen + x + y*16;
4415
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4416
4417
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4418
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4419
4420
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4421
4422
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4423 169672 nearby_screen.screen = screen;
4424 169672 nearby_screen.offx = offx;
4425 169672 nearby_screen.offy = offy;
4426
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4427 169672 }
4428 79928 }
4429
4430 48296 return nearby_screens;
4431
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4432
4433 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4434 {
4435 3658 nearby_screens_t nearby_screens;
4436
4437
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4438
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4439
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4440
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4441
4442
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4443
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4444
4445
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4446 {
4447
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4448 {
4449 18600 int screen = -1;
4450 mapscr* base_scr;
4451 int offx, offy;
4452
4453 18600 mapscr* maze_scr = maze_state.scr;
4454 18600 int maze_screen = maze_scr->screen;
4455
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4456
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4457 18600 int maze_screen_dx = x - maze_screen_x;
4458 18600 int maze_screen_dy = y - maze_screen_y;
4459 18600 int exitdir = maze_scr->exitdir;
4460
4461 bool should_draw_maze_screen;
4462
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4463 {
4464 9548 should_draw_maze_screen = true;
4465 9548 }
4466 else
4467 {
4468 9052 should_draw_maze_screen = true;
4469
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4470
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4471
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4472 }
4473
4474
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4475 {
4476 16048 screen = maze_state.scr->screen;
4477 16048 base_scr = maze_state.scr;
4478
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4479 16048 }
4480
4481
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4482 {
4483 2552 screen = cur_screen + x + y*16;
4484
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4485
4486
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4487
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4488
4489
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4490 2552 }
4491
4492
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4493 18600 nearby_screen.screen = screen;
4494 18600 nearby_screen.offx = offx;
4495 18600 nearby_screen.offy = offy;
4496
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4497 18600 }
4498 7308 }
4499
4500 3658 return nearby_screens;
4501
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4502
4503 16128838 static nearby_screens_t get_nearby_screens()
4504 {
4505
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 16119624 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
16128838 if (maze_state.active && maze_state.loopy)
4506 3658 return get_nearby_screens_smooth_maze();
4507
4508
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 16076884 times.
16125180 if (is_in_scrolling_region())
4509 48296 return get_nearby_screens_scrolling_region();
4510
4511 16076884 return get_nearby_screens_non_scrolling_region();
4512 16128838 }
4513
4514 209902643 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4515 {
4516
2/2
✓ Branch 0 taken 211687245 times.
✓ Branch 1 taken 209902643 times.
421589888 for (auto& nearby_screen : nearby_screens)
4517 211687245 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4518 209902643 }
4519
4520 145244054 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4521 {
4522
2/2
✓ Branch 0 taken 32299148 times.
✓ Branch 1 taken 112944906 times.
145244054 if(layer != msgstr_layer) return;
4523
2/2
✓ Branch 0 taken 16128054 times.
✓ Branch 1 taken 16171094 times.
32299148 if(!dest) dest = framebuf;
4524
4525
2/2
✓ Branch 0 taken 1456533 times.
✓ Branch 1 taken 30842615 times.
32299148 if(!(msg_bg_display_buf->clip))
4526 {
4527 1456533 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4528 1456533 }
4529
4530
2/2
✓ Branch 0 taken 1456533 times.
✓ Branch 1 taken 30842615 times.
32299148 if(!(msg_portrait_display_buf->clip))
4531 {
4532 1456533 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4533 1456533 }
4534
4535
2/2
✓ Branch 0 taken 1483347 times.
✓ Branch 1 taken 30815801 times.
32299148 if(!(msg_txt_display_buf->clip))
4536 {
4537 1483347 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4538 1483347 }
4539 145244054 }
4540
4541 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4542
4543 64515352 static void set_draw_screen_clip(BITMAP* bmp)
4544 {
4545 64515352 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4546 64515352 }
4547
4548 17580 static void draw_sprites(BITMAP* dest, set<sprite*, SpriteSorter>& sprite_set, set<sprite*, SpriteSorter>::iterator& it, word upto_z)
4549 {
4550 17580 bool checkz = upto_z != word(-1); // max value represents "infinity" height
4551
6/6
✓ Branch 0 taken 11145 times.
✓ Branch 1 taken 6435 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 6275 times.
✓ Branch 4 taken 12905 times.
✓ Branch 5 taken 4675 times.
17580 if(it == sprite_set.end() || (checkz && (*it)->total_z() >= upto_z))
4552 12905 return; // no sprites to draw remaining
4553 // Just clips sprites if in a repeating, smooth maze.
4554
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 bool do_clip = maze_state.active && maze_state.loopy;
4555
4556
4557
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4558 {
4559 int maze_screen = maze_state.scr->screen;
4560 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4561 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4562 }
4563
6/6
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 32443 times.
✓ Branch 2 taken 160 times.
✓ Branch 3 taken 32283 times.
✓ Branch 4 taken 4675 times.
✓ Branch 5 taken 30698 times.
67816 while(it != sprite_set.end() && (!checkz || (*it)->total_z() < upto_z))
4564 {
4565 30698 sprite* spr = *it;
4566
2/2
✓ Branch 0 taken 27768 times.
✓ Branch 1 taken 2930 times.
30698 if(spr == &Hero) // Draw the Hero
4567 {
4568 2930 decorations.draw2(dest,true);
4569 2930 Hero.draw(dest);
4570 2930 decorations.draw(dest,true);
4571
4572 // Draw enemies holding the Hero directly above the Hero
4573
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 for(int32_t i=0; i<guys.Count(); i++)
4574 {
4575 if(((enemy*)guys.spr(i))->type == eeWALK)
4576 if(((eStalfos*)guys.spr(i))->hashero)
4577 guys.spr(i)->draw(dest);
4578 else if(((enemy*)guys.spr(i))->type == eeWALLM)
4579 if(((eWallM*)guys.spr(i))->hashero)
4580 guys.spr(i)->draw(dest);
4581 }
4582 2930 }
4583
2/2
✓ Branch 0 taken 24838 times.
✓ Branch 1 taken 2930 times.
27768 else if(spr == &mblock2) // Draw the moving pushblock
4584 {
4585 2930 mblock2.draw(dest, -1);
4586 2930 do_primitives(dest, SPLAYER_MOVINGBLOCK);
4587 2930 }
4588
2/4
✓ Branch 0 taken 24838 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 24838 times.
24838 else if(enemy* e = dynamic_cast<enemy*>(spr))
4589 {
4590 e->draw(dest);
4591 e->draw2(dest); // used specifically for eGleeok/esGleeok
4592 }
4593 24838 else spr->draw(dest);
4594 30698 ++it;
4595 }
4596
1/2
✓ Branch 0 taken 4675 times.
✗ Branch 1 not taken.
4675 if(do_clip)
4597 clear_clip_rect(dest);
4598 17580 }
4599
4600 11991 static void draw_high_darkness(BITMAP* dest)
4601 {
4602 11991 do_primitives(dest, SPLAYER_DARKROOM_UNDER);
4603 11991 set_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
4604
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
4605 {
4606 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
4607 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
4608 }
4609
4610 11991 color_map = &trans_table2;
4611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
4612 {
4613 draw_trans_sprite(dest, darkscr_bmp, 0, 0);
4614 if(get_qr(qr_NEWDARK_TRANS_STACKING))
4615 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
4616 }
4617 else
4618 {
4619 11991 masked_blit(darkscr_bmp, dest, 0, 0, 0, 0, dest->w, dest->h);
4620 11991 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
4621 }
4622 11991 color_map = &trans_table;
4623
4624 11991 set_clip_rect(dest, 0, 0, dest->w, dest->h);
4625 11991 do_primitives(dest, SPLAYER_DARKROOM_OVER);
4626 11991 }
4627
4628 16171094 static void draw_screen_post_passive_subscreen(BITMAP* dest, bool any_dark)
4629 {
4630 16171094 draw_msgstr(6, dest);
4631
4632
1/2
✓ Branch 0 taken 16171094 times.
✗ Branch 1 not taken.
16171094 if (get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
4633 draw_msgstr(6, dest);
4634
4635
6/6
✓ Branch 0 taken 1900881 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 449198 times.
✓ Branch 3 taken 1451683 times.
✓ Branch 4 taken 437207 times.
✓ Branch 5 taken 11991 times.
16171094 if (get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
4636 11991 draw_high_darkness(dest);
4637
4638 16171094 _do_current_ffc_layer(dest, 7);
4639 16171094 draw_msgstr(7, dest);
4640 16171094 }
4641
4642 // Draws to framebuf.
4643 //
4644 // But if drawPassiveSubscreenSeparate is true: framebuf_no_passive_subscreen will also contain all
4645 // draws excluding the passive subscreen.
4646 16128838 void draw_screen(bool showhero, bool runGeneric, bool drawPassiveSubscreenSeparate)
4647 {
4648 16128838 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
4649 16128838 clear_info_bmp();
4650
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16128838 times.
16128838 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4651 {
4652 FFCore.doScriptMenuDraws();
4653 return;
4654 }
4655
4656
2/2
✓ Branch 0 taken 613439 times.
✓ Branch 1 taken 15515399 times.
16128838 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4657
4658 16128838 BITMAP* dest = framebuf;
4659 16128838 clear_bitmap(dest);
4660 16128838 clear_clip_rect(dest);
4661
4662 16128838 int32_t cmby2=0;
4663
4664 // Draw some background layers
4665 16128838 clear_bitmap(scrollbuf);
4666
4667 16128838 auto nearby_screens = get_nearby_screens();
4668
4669
2/2
✓ Branch 0 taken 16125908 times.
✓ Branch 1 taken 2930 times.
16128838 if (!classic_draw)
4670 {
4671
2/2
✓ Branch 0 taken 11720 times.
✓ Branch 1 taken 2930 times.
14650 for (int layer = -7; layer <= -4; ++layer)
4672 {
4673
1/2
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
11720 _do_current_ffc_layer(scrollbuf, layer);
4674
2/4
✓ Branch 0 taken 11720 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11720 times.
11720 if (script_drawing_commands.is_dirty(layer))
4675 do_primitives(scrollbuf, layer);
4676 11720 }
4677 2930 }
4678
4679 // Handle layer 2/3 possibly being background layers.
4680
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16125908 times.
16128838 if (classic_draw) // weird ordering (-3 > -2)
4681 {
4682
1/2
✓ Branch 0 taken 16125908 times.
✗ Branch 1 not taken.
32388134 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4683 16262226 mapscr* base_scr = screen_handles[0].base_scr;
4684
2/2
✓ Branch 0 taken 16120105 times.
✓ Branch 1 taken 142121 times.
16262226 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4685 142121 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4686 16262226 });
4687
4688 16125908 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4689
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 15983787 times.
16125908 if (l2bg)
4690 {
4691
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 do_layer_primitives(scrollbuf, 2);
4692
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 particles.draw(scrollbuf, true, 2);
4693 142121 }
4694
1/2
✓ Branch 0 taken 16125908 times.
✗ Branch 1 not taken.
16125908 _do_current_ffc_layer(scrollbuf, -2);
4695
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 15983787 times.
16125908 if (l2bg)
4696
1/2
✓ Branch 0 taken 142121 times.
✗ Branch 1 not taken.
142121 draw_msgstr(2, scrollbuf);
4697 16125908 }
4698
4699
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
32393994 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4700 16265156 mapscr* base_scr = screen_handles[0].base_scr;
4701
2/2
✓ Branch 0 taken 16030592 times.
✓ Branch 1 taken 234564 times.
16265156 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4702 234564 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4703 16265156 });
4704
4705
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 15894274 times.
16128838 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4706 {
4707
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 do_layer_primitives(scrollbuf, 3);
4708
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 particles.draw(scrollbuf, true, 3);
4709 234564 }
4710
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 _do_current_ffc_layer(scrollbuf, -3);
4711
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 15894274 times.
16128838 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4712
1/2
✓ Branch 0 taken 234564 times.
✗ Branch 1 not taken.
234564 draw_msgstr(3, scrollbuf);
4713
4714
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16125908 times.
16128838 if (!classic_draw)
4715 {
4716
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -3);
4717 // Actually use proper ordering (-3 < -2)
4718
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
5860 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4719 2930 mapscr* base_scr = screen_handles[0].base_scr;
4720
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4721 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4722 2930 });
4723
4724 2930 bool l2bg = XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG);
4725
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4726 {
4727 do_layer_primitives(scrollbuf, 2);
4728 particles.draw(scrollbuf, true, 2);
4729 }
4730
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -2);
4731
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if (l2bg)
4732 draw_msgstr(2, scrollbuf);
4733
4734
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -2);
4735
4736
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 _do_current_ffc_layer(scrollbuf, -1);
4737
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 do_primitives(scrollbuf, -1);
4738 2930 }
4739
4740 // Draw the main combo screens ("layer 0").
4741
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
32393994 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4742 16265156 mapscr* base_scr = screen_handles[0].base_scr;
4743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16265156 times.
16265156 if (lenscheck(base_scr, 0))
4744 {
4745 16265156 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4746 16265156 }
4747 16265156 });
4748
4749
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16128838 times.
16128838 if (lenscheck(hero_scr, 0))
4750 {
4751
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15662789 times.
16128838 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4752
3/4
✓ Branch 0 taken 466049 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 461913 times.
470185 if(mblock2.draw(scrollbuf,0))
4753
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4754 16128838 }
4755
4756 // Lens hints, then primitives, then particles.
4757
6/10
✓ Branch 0 taken 16118809 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 16118809 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16118809 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
16128838 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4758 {
4759
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4760
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4761 5876 }
4762
4763
2/4
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16128838 times.
✗ Branch 3 not taken.
16128838 if(show_layers[0] && lenscheck(hero_scr,0))
4764
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 do_primitives(scrollbuf, 0);
4765
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 particles.draw(scrollbuf, true, 0);
4766
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 _do_current_ffc_layer(scrollbuf, 0);
4767
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 draw_msgstr(0, scrollbuf);
4768
4769
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 set_draw_screen_clip(scrollbuf);
4770
4771 16128838 bool hero_draw_done = false;
4772
4/6
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16094086 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 16094086 times.
✗ Branch 5 not taken.
16128838 bool is_cave_walking = ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom));
4773
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15785579 times.
16128838 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4774 {
4775
4/4
✓ Branch 0 taken 15783701 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 15695317 times.
15785579 if(showhero && is_cave_walking)
4776 {
4777 88384 hero_draw_done = true;
4778
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4779 {
4780 34752 cmby2=16;
4781 34752 }
4782
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4783 {
4784 53632 cmby2=-16;
4785 53632 }
4786
4787
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4788
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4789
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4790
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4791
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4792
4793
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4794
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4795
4796
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4797 {
4798
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4799
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4800 15232 }
4801 88384 }
4802 15785579 }
4803
4804
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 16128838 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16128838 if (get_qr(qr_HERO_DIVE_UNDER_LAYER_1) && Hero.isDiving())
4805 {
4806 Hero.draw_under(scrollbuf);
4807 decorations.draw2(scrollbuf,true);
4808 Hero.draw(scrollbuf);
4809 decorations.draw(scrollbuf,true);
4810 hero_draw_done = true;
4811 }
4812
4813
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
32393994 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4814 16265156 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4815 16265156 });
4816
4817
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 do_layer_primitives(scrollbuf, 1);
4818
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 particles.draw(scrollbuf, true, 1);
4819
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 _do_current_ffc_layer(scrollbuf, 1);
4820
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 draw_msgstr(1, scrollbuf);
4821
4822 // Handle layer 2 NOT being used as background layers.
4823
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
32393994 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4824 16265156 mapscr* base_scr = screen_handles[0].base_scr;
4825
2/2
✓ Branch 0 taken 142121 times.
✓ Branch 1 taken 16123035 times.
16265156 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4826 16123035 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4827 16265156 });
4828
4829
2/2
✓ Branch 0 taken 15986717 times.
✓ Branch 1 taken 142121 times.
16128838 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4830 {
4831
1/2
✓ Branch 0 taken 15986717 times.
✗ Branch 1 not taken.
15986717 do_layer_primitives(scrollbuf, 2);
4832
1/2
✓ Branch 0 taken 15986717 times.
✗ Branch 1 not taken.
15986717 particles.draw(scrollbuf, true, 2);
4833 15986717 }
4834
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 _do_current_ffc_layer(scrollbuf, 2);
4835
2/2
✓ Branch 0 taken 15986717 times.
✓ Branch 1 taken 142121 times.
16128838 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4836
1/2
✓ Branch 0 taken 15986717 times.
✗ Branch 1 not taken.
15986717 draw_msgstr(2, scrollbuf);
4837
4838
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4839
4840
2/2
✓ Branch 0 taken 15785579 times.
✓ Branch 1 taken 343259 times.
16128838 if(get_qr(qr_LAYER12UNDERCAVE))
4841 {
4842
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
343259 if(showhero && is_cave_walking)
4843 {
4844 hero_draw_done = true;
4845 if(Hero.getAction()==climbcovertop)
4846 {
4847 cmby2=16;
4848 }
4849 else if(Hero.getAction()==climbcoverbottom)
4850 {
4851 cmby2=-16;
4852 }
4853
4854 decorations.draw2(scrollbuf,true);
4855 Hero.draw(scrollbuf);
4856 decorations.draw(scrollbuf,true);
4857 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4858 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4859
4860 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4861 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4862
4863 if(int32_t(Hero.getX())&15)
4864 {
4865 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4866 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4867 }
4868 }
4869 343259 }
4870
4871
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15662789 times.
16128838 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4872 {
4873
1/2
✓ Branch 0 taken 15662789 times.
✗ Branch 1 not taken.
31461896 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4874 15799107 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4875
2/2
✓ Branch 0 taken 14478915 times.
✓ Branch 1 taken 1320192 times.
15799107 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4876 {
4877 1320192 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4878 1320192 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4879 1320192 }
4880 15799107 });
4881
4882
1/2
✓ Branch 0 taken 15662789 times.
✗ Branch 1 not taken.
15662789 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4883 15662789 }
4884
4885 // Show walkflags cheat
4886
2/4
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16128838 times.
16128838 if (show_walkflags || show_effectflags)
4887 {
4888 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4889 do_walkflags(screen_handles, offx, offy);
4890 do_effectflags(screen_handles[0].base_scr, offx, offy);
4891 });
4892
4893 do_walkflags(0, 0);
4894 }
4895
4896
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4897
4898 // Lens hints, doors etc.
4899
4/8
✓ Branch 0 taken 16118809 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 16118809 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 16118809 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
16128838 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4900 {
4901
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4902 {
4903
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4904
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4905 4153 }
4906
4907
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4908
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4909 10029 }
4910
4911 // Blit those layers onto dest (framebuf)
4912
4913
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 set_draw_screen_clip(dest);
4914
4915
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 blit(scrollbuf, dest, 0, 0, 0, 0, 256, 232);
4916
4917 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4918 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4919
4920 // Draw the subscreen, without clipping
4921
2/2
✓ Branch 0 taken 9251384 times.
✓ Branch 1 taken 6877454 times.
16128838 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4922 {
4923 9251384 bool dotime = false;
4924
4/6
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412853 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412853 times.
✗ Branch 5 not taken.
9251384 if (replay_version_check(22)) dotime = game->should_show_time();
4925
1/2
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
9251384 put_passive_subscr(dest, 0, 0, dotime, sspUP);
4926 9251384 }
4927
4928 // Draw some sprites onto dest
4929
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 set_clip_rect(dest,0,0,256,232);
4930
4931
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 16029342 times.
16128838 if(!(pricesdisplaybuf->clip))
4932 {
4933
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,dest,0,0,0,playing_field_offset,256,176);
4934 99496 }
4935
4936
5/6
✓ Branch 0 taken 16083212 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16076884 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16128838 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4937 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
4938
4939
4/4
✓ Branch 0 taken 16126960 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 16038576 times.
✓ Branch 3 taken 88384 times.
16128838 if(showhero && !hero_draw_done)
4940 {
4941
1/2
✓ Branch 0 taken 16038576 times.
✗ Branch 1 not taken.
16038576 Hero.draw_under(dest);
4942
4943
3/4
✓ Branch 0 taken 16038576 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15897191 times.
16038576 if(Hero.isSwimming())
4944 {
4945
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(dest,true);
4946
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(dest);
4947
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(dest,true);
4948 141385 hero_draw_done = true;
4949 141385 }
4950 16038576 }
4951
4952 16128838 set<sprite*, SpriteSorter> sorted_sprites;
4953 16128838 vector<sprite*> temp_sprites;
4954 16128838 std::function<bool(sprite&)> add_sprite = [&](sprite& spr)
4955 {
4956 sorted_sprites.insert(&spr);
4957 return false;
4958 };
4959
4960
2/2
✓ Branch 0 taken 16125908 times.
✓ Branch 1 taken 2930 times.
16128838 if (classic_draw)
4961 {
4962
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 16099813 times.
16125908 if(drawguys)
4963 {
4964
4/4
✓ Branch 0 taken 1982674 times.
✓ Branch 1 taken 14117139 times.
✓ Branch 2 taken 991089 times.
✓ Branch 3 taken 991585 times.
16099813 if(get_qr(qr_NOFLICKER) || (frame&1))
4965 {
4966 // Just clips sprites if in a repeating, smooth maze.
4967
2/2
✓ Branch 0 taken 15099014 times.
✓ Branch 1 taken 9214 times.
15108228 bool do_clip = maze_state.active && maze_state.loopy;
4968
4969
1/2
✓ Branch 0 taken 15108228 times.
✗ Branch 1 not taken.
15108228 if(!get_qr(qr_OLD_WEAPON_DRAW_ANIMATE_TIMING))
4970 {
4971 if (do_clip)
4972 {
4973 Ewpns.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS));
4974 Lwpns.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS));
4975 }
4976 else
4977 {
4978 Ewpns.drawshadow(dest,get_qr(qr_TRANSSHADOWS),true);
4979 Lwpns.drawshadow(dest,get_qr(qr_TRANSSHADOWS),true);
4980 }
4981 }
4982
3/4
✓ Branch 0 taken 24913302 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9805074 times.
✓ Branch 3 taken 15108228 times.
24913302 for(int32_t i=0; i<Ewpns.Count(); i++)
4983 {
4984
3/4
✓ Branch 0 taken 9805074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 250942 times.
✓ Branch 3 taken 9554132 times.
9805074 if(((weapon *)Ewpns.spr(i))->behind)
4985
2/4
✓ Branch 0 taken 250942 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 250942 times.
✗ Branch 3 not taken.
250942 Ewpns.spr(i)->draw(dest);
4986 9805074 }
4987
1/2
✓ Branch 0 taken 15108228 times.
✗ Branch 1 not taken.
15108228 do_primitives(dest, SPLAYER_EWEAP_BEHIND_DRAW);
4988
4989
3/4
✓ Branch 0 taken 21292219 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6183991 times.
✓ Branch 3 taken 15108228 times.
21292219 for(int32_t i=0; i<Lwpns.Count(); i++)
4990 {
4991
3/4
✓ Branch 0 taken 6183991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206996 times.
✓ Branch 3 taken 4976995 times.
6183991 if(((weapon *)Lwpns.spr(i))->behind)
4992
2/4
✓ Branch 0 taken 1206996 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1206996 times.
✗ Branch 3 not taken.
1206996 Lwpns.spr(i)->draw(dest);
4993 6183991 }
4994
1/2
✓ Branch 0 taken 15108228 times.
✗ Branch 1 not taken.
15108228 do_primitives(dest, SPLAYER_LWEAP_BEHIND_DRAW);
4995
4996
6/6
✓ Branch 0 taken 10371364 times.
✓ Branch 1 taken 4736864 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 9023064 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
15108228 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4997 {
4998
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9693417 times.
9697075 if (do_clip)
4999
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(dest,get_qr(qr_TRANSSHADOWS)!=0);
5000 else
5001
1/2
✓ Branch 0 taken 9693417 times.
✗ Branch 1 not taken.
9693417 guys.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0,true);
5002 9697075 }
5003
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15104570 times.
15108228 if (do_clip)
5004
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(dest);
5005 else
5006
1/2
✓ Branch 0 taken 15104570 times.
✗ Branch 1 not taken.
15104570 guys.draw(dest,true);
5007
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15104570 times.
15108228 if (do_clip)
5008 {
5009 3658 int maze_screen = maze_state.scr->screen;
5010
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
5011
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
5012 3658 }
5013
1/2
✓ Branch 0 taken 15108228 times.
✗ Branch 1 not taken.
15108228 do_primitives(dest, SPLAYER_NPC_DRAW);
5014
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15104570 times.
15108228 if (do_clip)
5015
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(dest);
5016
5017
1/2
✓ Branch 0 taken 15108228 times.
✗ Branch 1 not taken.
15108228 chainlinks.draw(dest,true);
5018
1/2
✓ Branch 0 taken 15108228 times.
✗ Branch 1 not taken.
15108228 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5019 //Lwpns.draw(dest,true);
5020
5021
3/4
✓ Branch 0 taken 24913302 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9805074 times.
✓ Branch 3 taken 15108228 times.
24913302 for(int32_t i=0; i<Ewpns.Count(); i++)
5022 {
5023
3/4
✓ Branch 0 taken 9805074 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9554132 times.
✓ Branch 3 taken 250942 times.
9805074 if(!((weapon *)Ewpns.spr(i))->behind)
5024
2/4
✓ Branch 0 taken 9554132 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9554132 times.
✗ Branch 3 not taken.
9554132 Ewpns.spr(i)->draw(dest);
5025 9805074 }
5026
1/2
✓ Branch 0 taken 15108228 times.
✗ Branch 1 not taken.
15108228 do_primitives(dest, SPLAYER_EWEAP_FRONT_DRAW);
5027
5028
3/4
✓ Branch 0 taken 21292219 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6183991 times.
✓ Branch 3 taken 15108228 times.
21292219 for(int32_t i=0; i<Lwpns.Count(); i++)
5029 {
5030
3/4
✓ Branch 0 taken 6183991 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4976995 times.
✓ Branch 3 taken 1206996 times.
6183991 if(!((weapon *)Lwpns.spr(i))->behind)
5031
2/4
✓ Branch 0 taken 4976995 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4976995 times.
✗ Branch 3 not taken.
4976995 Lwpns.spr(i)->draw(dest);
5032 6183991 }
5033
1/2
✓ Branch 0 taken 15108228 times.
✗ Branch 1 not taken.
15108228 do_primitives(dest, SPLAYER_LWEAP_FRONT_DRAW);
5034
5035
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15104570 times.
15108228 if (do_clip)
5036
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(dest);
5037 else
5038
1/2
✓ Branch 0 taken 15104570 times.
✗ Branch 1 not taken.
15104570 items.draw(dest,true);
5039
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15104570 times.
15108228 if (do_clip)
5040 {
5041 3658 int maze_screen = maze_state.scr->screen;
5042
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
5043
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(dest, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
5044 3658 }
5045
1/2
✓ Branch 0 taken 15108228 times.
✗ Branch 1 not taken.
15108228 do_primitives(dest, SPLAYER_ITEMSPRITE_DRAW);
5046
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 15104570 times.
15108228 if (do_clip)
5047
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(dest);
5048 15108228 }
5049 else
5050 {
5051
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
5052 {
5053
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
5054
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(dest);
5055 505372 }
5056
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_EWEAP_BEHIND_DRAW);
5057
5058
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
5059 {
5060
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 231146 times.
231146 if(((weapon *)Lwpns.spr(i))->behind)
5061 Lwpns.spr(i)->draw(dest);
5062 231146 }
5063
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_LWEAP_BEHIND_DRAW);
5064
5065
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991585 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5066 {
5067
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0,true);
5068 228620 }
5069
5070
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 items.draw(dest,false);
5071
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_ITEMSPRITE_DRAW);
5072
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 chainlinks.draw(dest,false);
5073
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5074 //Lwpns.draw(dest,false);
5075
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 guys.draw(dest,false);
5076
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_NPC_DRAW);
5077
5078
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
5079 {
5080
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
5081 {
5082
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(dest);
5083 496727 }
5084 505372 }
5085
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_EWEAP_FRONT_DRAW);
5086
5087
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
5088 {
5089
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 if(!((weapon *)Lwpns.spr(i))->behind)
5090 {
5091
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 Lwpns.spr(i)->draw(dest);
5092 231146 }
5093 231146 }
5094
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(dest, SPLAYER_LWEAP_FRONT_DRAW);
5095 }
5096
5097
1/2
✓ Branch 0 taken 16099813 times.
✗ Branch 1 not taken.
16099813 guys.draw2(dest,true);
5098 16099813 }
5099
5100
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16125908 times.
16125908 if(mirror_portal.destdmap > -1)
5101 mirror_portal.draw(dest);
5102
1/2
✓ Branch 0 taken 16125908 times.
✗ Branch 1 not taken.
16125908 portals.draw(dest,true);
5103
5104
4/4
✓ Branch 0 taken 16124030 times.
✓ Branch 1 taken 1878 times.
✓ Branch 2 taken 88384 times.
✓ Branch 3 taken 16035646 times.
16125908 if(showhero && !is_cave_walking)
5105 {
5106
2/2
✓ Branch 0 taken 15576013 times.
✓ Branch 1 taken 459633 times.
16035646 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5107 {
5108
1/2
✓ Branch 0 taken 15576013 times.
✗ Branch 1 not taken.
15576013 mblock2.draw(dest,-1);
5109
1/2
✓ Branch 0 taken 15576013 times.
✗ Branch 1 not taken.
15576013 do_primitives(dest, SPLAYER_MOVINGBLOCK);
5110 15576013 }
5111
2/2
✓ Branch 0 taken 15894261 times.
✓ Branch 1 taken 141385 times.
16035646 if(!hero_draw_done)
5112 {
5113
8/12
✓ Branch 0 taken 15894261 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15894261 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15875091 times.
✓ Branch 5 taken 19170 times.
✓ Branch 6 taken 15875091 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15875091 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15892891 times.
15894261 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5114 {
5115
2/2
✓ Branch 0 taken 18485 times.
✓ Branch 1 taken 15875776 times.
15894261 Hero.drawshadow(dest,get_qr(qr_TRANSSHADOWS)!=0);
5116 18485 }
5117
5118
6/8
✓ Branch 0 taken 15894261 times.
✓ Branch 1 taken 15875776 times.
✓ Branch 2 taken 15894261 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15894261 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15880197 times.
✓ Branch 7 taken 14064 times.
18485 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
5119 {
5120
1/2
✓ Branch 0 taken 15880197 times.
✗ Branch 1 not taken.
15880197 decorations.draw2(dest,true);
5121
1/2
✓ Branch 0 taken 15880197 times.
✗ Branch 1 not taken.
15880197 Hero.draw(dest);
5122
1/2
✓ Branch 0 taken 15880197 times.
✗ Branch 1 not taken.
15880197 decorations.draw(dest,true);
5123 15880197 hero_draw_done = true;
5124 15880197 }
5125 15894261 }
5126 16035646 }
5127
5128
3/4
✓ Branch 0 taken 56543476 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40417568 times.
✓ Branch 3 taken 16125908 times.
56543476 for(int32_t i=0; i<guys.Count(); i++)
5129 {
5130
3/4
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16520322 times.
✓ Branch 3 taken 23897246 times.
40417568 if(((enemy*)guys.spr(i))->type == eeWALK)
5131 {
5132
3/4
✓ Branch 0 taken 16520322 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7965 times.
✓ Branch 3 taken 16512357 times.
16520322 if(((eStalfos*)guys.spr(i))->hashero)
5133 {
5134
2/4
✓ Branch 0 taken 7965 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7965 times.
✗ Branch 3 not taken.
7965 guys.spr(i)->draw(dest);
5135 7965 }
5136 16520322 }
5137
5138
3/4
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 39910406 times.
40417568 if(((enemy*)guys.spr(i))->type == eeWALLM)
5139 {
5140
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
5141 {
5142
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(dest);
5143 1329 }
5144 507162 }
5145
5146
11/20
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40417568 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40417568 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 40417568 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 40417568 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 40417568 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 40417568 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 40417568 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 40417568 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1523506 times.
✓ Branch 19 taken 38894062 times.
40417568 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
5147 {
5148 //Jumping enemies in front of Hero.
5149
2/4
✓ Branch 0 taken 1523506 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1523506 times.
✗ Branch 3 not taken.
1523506 guys.spr(i)->draw(dest);
5150 1523506 }
5151
1/2
✓ Branch 0 taken 40417568 times.
✗ Branch 1 not taken.
40417568 do_primitives(dest, SPLAYER_NPC_ABOVEPLAYER_DRAW);
5152 40417568 }
5153 16125908 }
5154 else
5155 {
5156
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(drawguys)
5157 {
5158
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 chainlinks.forEach(add_sprite);
5159
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
5860 bool show_enemy_shadows = (get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1));
5160 25837 auto add_spr_shadow = [&](sprite& spr)
5161 {
5162 22907 sorted_sprites.insert(&spr);
5163
3/4
✓ Branch 0 taken 1291 times.
✓ Branch 1 taken 21616 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1291 times.
22907 if(spr.total_z() > 0 && spr.can_drawshadow())
5164 {
5165
1/2
✓ Branch 0 taken 1291 times.
✗ Branch 1 not taken.
1291 tempsprite_shadow* shadow = new tempsprite_shadow(&spr);
5166 1291 sorted_sprites.insert(shadow);
5167 1291 temp_sprites.push_back(shadow);
5168 1291 }
5169 22907 return false;
5170 };
5171
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Lwpns.forEach(add_spr_shadow);
5172
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 Ewpns.forEach(add_spr_shadow);
5173
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 items.forEach(add_spr_shadow);
5174
4/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 2930 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2930 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 2930 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
2930 guys.forEach(show_enemy_shadows ? add_spr_shadow : add_sprite);
5175 2930 }
5176
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 if(showhero && !hero_draw_done)
5177 {
5178
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&Hero);
5179
9/14
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2290 times.
✓ Branch 5 taken 640 times.
✓ Branch 6 taken 2290 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2290 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2930 times.
✓ Branch 12 taken 2290 times.
✓ Branch 13 taken 2290 times.
2930 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
5180 {
5181
3/4
✓ Branch 0 taken 640 times.
✓ Branch 1 taken 4580 times.
✓ Branch 2 taken 640 times.
✗ Branch 3 not taken.
5220 tempsprite_shadow* shadow = new tempsprite_shadow(&Hero);
5182
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 sorted_sprites.insert(shadow);
5183
1/2
✓ Branch 0 taken 640 times.
✗ Branch 1 not taken.
640 temp_sprites.push_back(shadow);
5184 640 }
5185 2930 }
5186
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2930 times.
2930 if(mirror_portal.destdmap > -1)
5187 sorted_sprites.insert(&mirror_portal);
5188
2/4
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2930 times.
✗ Branch 3 not taken.
2930 portals.forEach(add_sprite);
5189
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
5190
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 sorted_sprites.insert(&mblock2);
5191 }
5192 16128838 auto sprite_it = sorted_sprites.begin();
5193
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16125908 times.
16128838 if (!classic_draw)
5194
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_GROUND]);
5195
5196 // Draw some layers onto dest
5197
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 set_draw_screen_clip(dest);
5198
5/6
✓ Branch 0 taken 16083212 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16076884 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16128838 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5199 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5200
5201 // Handle layer 3 NOT being used as background layers.
5202
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
32393994 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5203 16265156 mapscr* base_scr = screen_handles[0].base_scr;
5204
2/2
✓ Branch 0 taken 234564 times.
✓ Branch 1 taken 16030592 times.
16265156 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5205 16030592 do_layer(dest, 0, screen_handles[3], offx, offy);
5206 16265156 });
5207
5208
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16125908 times.
16128838 if (!classic_draw)
5209
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_3]);
5210
5211
2/2
✓ Branch 0 taken 15894274 times.
✓ Branch 1 taken 234564 times.
16128838 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5212 {
5213
1/2
✓ Branch 0 taken 15894274 times.
✗ Branch 1 not taken.
15894274 do_layer_primitives(dest, 3);
5214
1/2
✓ Branch 0 taken 15894274 times.
✗ Branch 1 not taken.
15894274 particles.draw(dest, true, 3);
5215 15894274 }
5216
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 _do_current_ffc_layer(dest, 3);
5217
2/2
✓ Branch 0 taken 15894274 times.
✓ Branch 1 taken 234564 times.
16128838 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5218
1/2
✓ Branch 0 taken 15894274 times.
✗ Branch 1 not taken.
15894274 draw_msgstr(3);
5219
5220
5221
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
32393994 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5222 16265156 do_layer(dest, 0, screen_handles[4], offx, offy);
5223 16265156 });
5224
5225
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16125908 times.
16128838 if (!classic_draw)
5226
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_4]);
5227
5228
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 do_layer_primitives(dest, 4);
5229
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 particles.draw(dest, true, 4);
5230
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 _do_current_ffc_layer(dest, 4);
5231
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 draw_msgstr(4);
5232
5233
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
32393994 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5234 16265156 do_layer(dest, -1, screen_handles[0], offx, offy);
5235
2/2
✓ Branch 0 taken 14402748 times.
✓ Branch 1 taken 1862408 times.
16265156 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
5236 {
5237 1862408 do_layer(dest, -1, screen_handles[1], offx, offy);
5238 1862408 do_layer(dest, -1, screen_handles[2], offx, offy);
5239 1862408 }
5240 16265156 });
5241
5242
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 do_primitives(dest, SPLAYER_OVERHEAD_CMB);
5243
5244 // Draw some flying sprites onto dest
5245
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 clear_clip_rect(dest);
5246
5/6
✓ Branch 0 taken 16083212 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 16076884 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
16128838 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5247 add_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5248
5249
2/2
✓ Branch 0 taken 16125908 times.
✓ Branch 1 taken 2930 times.
16128838 if (classic_draw)
5250 {
5251 //Jumping Hero and jumping enemies are drawn on this layer.
5252
5/8
✓ Branch 0 taken 16125908 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16125908 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16125908 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14064 times.
✓ Branch 7 taken 16111844 times.
16125908 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
5253 {
5254
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw2(dest,false);
5255
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 Hero.draw(dest);
5256
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 chainlinks.draw(dest,true);
5257
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(dest, SPLAYER_CHAINLINK_DRAW);
5258
5259
3/4
✓ Branch 0 taken 16806 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14064 times.
16806 for(int32_t i=0; i<Lwpns.Count(); i++)
5260 {
5261
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
5262 {
5263
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(dest);
5264 239 }
5265 2742 }
5266
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(dest, SPLAYER_LWEAP_ABOVE_DRAW);
5267
5268
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw(dest,false);
5269 14064 }
5270
5271
5/6
✓ Branch 0 taken 3872571 times.
✓ Branch 1 taken 12253337 times.
✓ Branch 2 taken 44336928 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32083591 times.
✓ Branch 5 taken 12253337 times.
48209499 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
5272 {
5273
13/22
✓ Branch 0 taken 32083591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32083591 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27177493 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27177493 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27177493 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27177493 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27177493 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27177493 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27177493 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27177493 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27170925 times.
32083591 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
5274 {
5275
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(dest);
5276 4912666 }
5277 44336928 }
5278 else
5279 {
5280
3/4
✓ Branch 0 taken 12206548 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8333977 times.
✓ Branch 3 taken 3872571 times.
12206548 for(int32_t i=0; i<guys.Count(); i++)
5281 {
5282
13/22
✓ Branch 0 taken 8333977 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8333977 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6997572 times.
✓ Branch 5 taken 1336405 times.
✓ Branch 6 taken 6997572 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6997572 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6997572 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6478745 times.
✓ Branch 13 taken 518827 times.
✓ Branch 14 taken 6478745 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 6478745 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 6478745 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 6478745 times.
8333977 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
5283 {
5284
2/4
✓ Branch 0 taken 1855232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1855232 times.
✗ Branch 3 not taken.
1855232 guys.spr(i)->draw(dest);
5285 1855232 }
5286 8333977 }
5287 }
5288
1/2
✓ Branch 0 taken 16125908 times.
✗ Branch 1 not taken.
16125908 do_primitives(dest, SPLAYER_NPC_AIRBORNE_DRAW);
5289 16125908 }
5290
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 else draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_OVERHEAD]);
5291
5292 // Draw the Moving Fairy above layer 3
5293
3/4
✓ Branch 0 taken 19452104 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3323266 times.
✓ Branch 3 taken 16128838 times.
19452104 for(int32_t i=0; i<items.Count(); i++)
5294
6/8
✓ Branch 0 taken 3323266 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 70250 times.
✓ Branch 3 taken 3253016 times.
✓ Branch 4 taken 70250 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60536 times.
✓ Branch 7 taken 9714 times.
3383802 if(itemsbuf[items.spr(i)->id].type == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
5295
2/4
✓ Branch 0 taken 60536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60536 times.
✗ Branch 3 not taken.
60536 items.spr(i)->draw(dest);
5296
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 do_primitives(dest, SPLAYER_FAIRYITEM_DRAW);
5297
5298 // Draw some layers onto dest
5299
5300
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 set_draw_screen_clip(dest);
5301
5302
2/2
✓ Branch 0 taken 16114486 times.
✓ Branch 1 taken 14352 times.
16128838 if (lightbeam_present)
5303 {
5304 14352 color_map = &trans_table2;
5305
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5306
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(dest, lightbeam_bmp, 0, playing_field_offset);
5307 else
5308
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, dest, 0, 0, 0, playing_field_offset, 256, 176);
5309 14352 color_map = &trans_table;
5310 14352 }
5311
5312
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
32393994 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5313 16265156 do_layer(dest, 0, screen_handles[5], offx, offy);
5314 16265156 });
5315
5316
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16125908 times.
16128838 if (!classic_draw)
5317
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, zinit.sprite_z_thresholds[SPRITE_THRESHOLD_5]);
5318
5319
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 do_layer_primitives(dest, 5);
5320
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 particles.draw(dest, true, 5);
5321
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 _do_current_ffc_layer(dest, 5);
5322
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 draw_msgstr(5);
5323
5324
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 _do_current_ffc_layer(dest, -1000); // 'overhead' freeform combos
5325
5326
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 do_primitives(dest, SPLAYER_OVERHEAD_FFC);
5327
5328
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
32393994 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5329 16265156 do_layer(dest, 0, screen_handles[6], offx, offy);
5330 16265156 });
5331
5332
2/2
✓ Branch 0 taken 2930 times.
✓ Branch 1 taken 16125908 times.
16128838 if (!classic_draw)
5333
1/2
✓ Branch 0 taken 2930 times.
✗ Branch 1 not taken.
2930 draw_sprites(dest, sorted_sprites, sprite_it, word(-1));
5334
5335
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 do_layer_primitives(dest, 6);
5336
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 particles.draw(dest, true, 6);
5337
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 _do_current_ffc_layer(dest, 6);
5338
5339 16128838 bool any_dark = false;
5340
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
32393994 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5341 16265156 mapscr* base_scr = screen_handles[0].scr;
5342 16265156 any_dark |= is_dark(base_scr);
5343 16265156 });
5344
5345 // Handle low drawn darkness
5346
4/4
✓ Branch 0 taken 1858625 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1511726 times.
✓ Branch 3 taken 346899 times.
16128838 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5347 {
5348
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
700032 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5349 353133 mapscr* base_scr = screen_handles[0].scr;
5350 353133 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5351 353133 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5352 353133 });
5353
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
346899 if(showhero)
5354
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
346899 Hero.calc_darkroom_hero(0, -playing_field_offset);
5355
1/2
✓ Branch 0 taken 346899 times.
✗ Branch 1 not taken.
700032 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5356 353133 mapscr* base_scr = screen_handles[0].scr;
5357
2/2
✓ Branch 0 taken 348403 times.
✓ Branch 1 taken 4730 times.
353133 if (!is_dark(base_scr))
5358 {
5359 4730 offy += playing_field_offset;
5360 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5361 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5362 4730 }
5363 353133 });
5364 346899 }
5365
5366 //Darkroom if under the subscreen
5367
6/6
✓ Branch 0 taken 1858625 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1409427 times.
✓ Branch 3 taken 449198 times.
✓ Branch 4 taken 334908 times.
✓ Branch 5 taken 1074519 times.
16128838 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5368 {
5369
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 do_primitives(dest, SPLAYER_DARKROOM_UNDER);
5370
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 set_clip_rect(dest, 0, playing_field_offset, dest->w, dest->h);
5371
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 334908 times.
334908 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5372 {
5373 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5374 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5375 }
5376
5377 334908 color_map = &trans_table2;
5378
2/2
✓ Branch 0 taken 15523 times.
✓ Branch 1 taken 319385 times.
334908 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5379 {
5380
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 draw_trans_sprite(dest, darkscr_bmp, 0, 0);
5381
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5382
1/2
✓ Branch 0 taken 15523 times.
✗ Branch 1 not taken.
15523 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
5383 15523 }
5384 else
5385 {
5386
1/2
✓ Branch 0 taken 319385 times.
✗ Branch 1 not taken.
319385 masked_blit(darkscr_bmp, dest, 0, 0, 0, 0, dest->w, dest->h);
5387
1/2
✓ Branch 0 taken 319385 times.
✗ Branch 1 not taken.
319385 draw_trans_sprite(dest, darkscr_bmp_trans, 0, 0);
5388 }
5389 334908 color_map = &trans_table;
5390
5391
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 set_clip_rect(dest, 0, 0, dest->w, dest->h);
5392
1/2
✓ Branch 0 taken 334908 times.
✗ Branch 1 not taken.
334908 do_primitives(dest, SPLAYER_DARKROOM_OVER);
5393 334908 }
5394
5395
3/6
✓ Branch 0 taken 51954 times.
✓ Branch 1 taken 16076884 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 51954 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
16128838 if (is_in_scrolling_region() && lensclk && !FFCore.system_suspend[susptLENS])
5396 {
5397 draw_lens_over(dest);
5398 --lensclk;
5399 }
5400
5401 // Draw some text on dest
5402
5403
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 set_clip_rect(dest,0,0,256,232);
5404
5405
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5406
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 draw_msgstr(6);
5407
5408 // Draw the subscreen, without clipping
5409
2/2
✓ Branch 0 taken 6877454 times.
✓ Branch 1 taken 9251384 times.
16128838 if(get_qr(qr_SUBSCREENOVERSPRITES))
5410 {
5411
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 6835198 times.
6877454 if (drawPassiveSubscreenSeparate)
5412
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 blit(dest, framebuf_no_passive_subscreen, 0, 0, 0, 0, dest->w, dest->h);
5413
5414
2/4
✓ Branch 0 taken 6877454 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6877454 times.
✗ Branch 3 not taken.
6877454 put_passive_subscr(dest, 0, 0, game->should_show_time(), sspUP);
5415
5416
1/2
✓ Branch 0 taken 6877454 times.
✗ Branch 1 not taken.
6877454 do_primitives(dest, 7);
5417
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 6835198 times.
6877454 if (drawPassiveSubscreenSeparate)
5418
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 do_primitives(framebuf_no_passive_subscreen, 7);
5419 6877454 }
5420
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9251384 times.
9251384 else if (!classic_draw)
5421 do_primitives(dest, 7);
5422
5423
1/2
✓ Branch 0 taken 16128838 times.
✗ Branch 1 not taken.
16128838 draw_screen_post_passive_subscreen(dest, any_dark);
5424
2/2
✓ Branch 0 taken 42256 times.
✓ Branch 1 taken 16086582 times.
16128838 if (drawPassiveSubscreenSeparate)
5425
1/2
✓ Branch 0 taken 42256 times.
✗ Branch 1 not taken.
42256 draw_screen_post_passive_subscreen(framebuf_no_passive_subscreen, any_dark);
5426
5427
2/2
✓ Branch 0 taken 15627294 times.
✓ Branch 1 taken 31756132 times.
16128838 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5428
3/4
✓ Branch 0 taken 15515399 times.
✓ Branch 1 taken 158873 times.
✓ Branch 2 taken 15515399 times.
✗ Branch 3 not taken.
15627294 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5429
5430
2/2
✓ Branch 0 taken 1931 times.
✓ Branch 1 taken 15674272 times.
15676203 for(sprite* spr : temp_sprites)
5431
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1931 times.
1931 delete spr;
5432 79186536 }
5433
5434 // TODO: separate setting door data and drawing door
5435 28153 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5436 {
5437
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28153 times.
28153 if (type > 8) return;
5438
5439 28153 int32_t d=scr->door_combo_set;
5440
5441
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12542 times.
28153 switch(type)
5442 {
5443 case dt_wall:
5444 case dt_walk:
5445 if(!even_walls)
5446 break;
5447 [[fallthrough]];
5448 case dt_pass:
5449
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12542 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5450 1036 break;
5451 [[fallthrough]];
5452 case dt_lock:
5453 case dt_shut:
5454 case dt_boss:
5455 case dt_olck:
5456 case dt_osht:
5457 case dt_obos:
5458 case dt_bomb:
5459
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5460 {
5461 case up:
5462 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5463 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5464 7259 scr->sflag[pos] = 0;
5465 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5466 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5467 7259 scr->sflag[pos+1] = 0;
5468 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5469 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5470 7259 scr->sflag[pos+16] = 0;
5471 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5472 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5473 7259 scr->sflag[pos+16+1] = 0;
5474
5475
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5476 {
5477 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5478 1824 DoorComboSets[d].doorcombo_u[type][0],
5479 1824 DoorComboSets[d].doorcset_u[type][0]);
5480 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5481 1824 DoorComboSets[d].doorcombo_u[type][1],
5482 1824 DoorComboSets[d].doorcset_u[type][1]);
5483 1824 }
5484
5485 7259 break;
5486
5487 case down:
5488 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5489 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5490 6784 scr->sflag[pos] = 0;
5491 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5492 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5493 6784 scr->sflag[pos+1] = 0;
5494 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5495 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5496 6784 scr->sflag[pos+16] = 0;
5497 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5498 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5499 6784 scr->sflag[pos+16+1] = 0;
5500
5501
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5502 {
5503 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5504 1321 DoorComboSets[d].doorcombo_d[type][2],
5505 1321 DoorComboSets[d].doorcset_d[type][2]);
5506 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5507 1321 DoorComboSets[d].doorcombo_d[type][3],
5508 1321 DoorComboSets[d].doorcset_d[type][3]);
5509 1321 }
5510
5511 6784 break;
5512
5513 case left:
5514 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5515 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5516 6362 scr->sflag[pos] = 0;
5517 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5518 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5519 6362 scr->sflag[pos+1] = 0;
5520 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5521 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5522 6362 scr->sflag[pos+16] = 0;
5523 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5524 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5525 6362 scr->sflag[pos+16+1] = 0;
5526 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5527 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5528 6362 scr->sflag[pos+32] = 0;
5529 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5530 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5531 6362 scr->sflag[pos+32+1] = 0;
5532
5533
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5534 {
5535 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5536 1489 DoorComboSets[d].doorcombo_l[type][0],
5537 1489 DoorComboSets[d].doorcset_l[type][0]);
5538 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5539 1489 DoorComboSets[d].doorcombo_l[type][2],
5540 1489 DoorComboSets[d].doorcset_l[type][2]);
5541 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5542 1489 DoorComboSets[d].doorcombo_l[type][4],
5543 1489 DoorComboSets[d].doorcset_l[type][4]);
5544 1489 }
5545
5546 6362 break;
5547
5548 case right:
5549 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5550 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5551 6712 scr->sflag[pos] = 0;
5552 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5553 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5554 6712 scr->sflag[pos+1] = 0;
5555 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5556 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5557 6712 scr->sflag[pos+16] = 0;
5558 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5559 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5560 6712 scr->sflag[pos+16+1] = 0;
5561 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5562 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5563 6712 scr->sflag[pos+32] = 0;
5564 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5565 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5566 6712 scr->sflag[pos+32+1] = 0;
5567
5568
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5569 {
5570 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5571 1654 DoorComboSets[d].doorcombo_r[type][0],
5572 1654 DoorComboSets[d].doorcset_r[type][0]);
5573 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5574 1654 DoorComboSets[d].doorcombo_r[type][2],
5575 1654 DoorComboSets[d].doorcset_r[type][2]);
5576 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5577 1654 DoorComboSets[d].doorcombo_r[type][4],
5578 1654 DoorComboSets[d].doorcset_r[type][4]);
5579 1654 }
5580
5581 6712 break;
5582 }
5583
5584 27117 break;
5585
5586 default:
5587 break;
5588 }
5589 28153 }
5590
5591 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5592 {
5593 706556 int32_t door_combo_set = scr->door_combo_set;
5594 706556 int32_t x = (pos&15)<<4;
5595 706556 int32_t y = (pos&0xF0);
5596 706556 int32_t d = door_combo_set;
5597 706556 x += offx;
5598 706556 y += offy;
5599
5600
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5601 {
5602 case up:
5603 322272 overcombo2(dest,x,y,
5604 161136 DoorComboSets[d].bombdoorcombo_u[0],
5605 161136 DoorComboSets[d].bombdoorcset_u[0]);
5606 322272 overcombo2(dest,x+16,y,
5607 161136 DoorComboSets[d].bombdoorcombo_u[1],
5608 161136 DoorComboSets[d].bombdoorcset_u[1]);
5609 161136 break;
5610
5611 case down:
5612 359286 overcombo2(dest,x,y,
5613 179643 DoorComboSets[d].bombdoorcombo_d[0],
5614 179643 DoorComboSets[d].bombdoorcset_d[0]);
5615 359286 overcombo2(dest,x+16,y,
5616 179643 DoorComboSets[d].bombdoorcombo_d[1],
5617 179643 DoorComboSets[d].bombdoorcset_d[1]);
5618 179643 break;
5619
5620 case left:
5621 392706 overcombo2(dest,x,y,
5622 196353 DoorComboSets[d].bombdoorcombo_l[0],
5623 196353 DoorComboSets[d].bombdoorcset_l[0]);
5624 392706 overcombo2(dest,x,y+16,
5625 196353 DoorComboSets[d].bombdoorcombo_l[1],
5626 196353 DoorComboSets[d].bombdoorcset_l[1]);
5627 392706 overcombo2(dest,x,y+16,
5628 196353 DoorComboSets[d].bombdoorcombo_l[2],
5629 196353 DoorComboSets[d].bombdoorcset_l[2]);
5630 196353 break;
5631
5632 case right:
5633 338848 overcombo2(dest,x,y,
5634 169424 DoorComboSets[d].bombdoorcombo_r[0],
5635 169424 DoorComboSets[d].bombdoorcset_r[0]);
5636 338848 overcombo2(dest,x,y+16,
5637 169424 DoorComboSets[d].bombdoorcombo_r[1],
5638 169424 DoorComboSets[d].bombdoorcset_r[1]);
5639 338848 overcombo2(dest,x,y+16,
5640 169424 DoorComboSets[d].bombdoorcombo_r[2],
5641 169424 DoorComboSets[d].bombdoorcset_r[2]);
5642 169424 break;
5643 }
5644 706556 }
5645
5646 47568 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5647 {
5648
7/8
✓ Branch 0 taken 47460 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22925 times.
✓ Branch 5 taken 24535 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22395 times.
47568 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5649 25173 return;
5650
5651 int32_t doortype;
5652
5653
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12492 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22395 switch(door)
5654 {
5655 case dWALL:
5656 doortype=dt_wall;
5657 break;
5658
5659 case dWALK:
5660 doortype=dt_walk;
5661 break;
5662
5663 case dOPEN:
5664 12492 doortype=dt_pass;
5665 12492 break;
5666
5667 case dLOCKED:
5668 910 doortype=dt_lock;
5669 910 break;
5670
5671 case dUNLOCKED:
5672 1553 doortype=dt_olck;
5673 1553 break;
5674
5675 case dSHUTTER:
5676
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5677 {
5678 doortype=dt_osht;
5679 get_screen_state(scr->screen).open_doors = -4;
5680 break;
5681 }
5682
5683 [[fallthrough]];
5684 case d1WAYSHUTTER:
5685 3714 doortype=dt_shut;
5686 3714 break;
5687
5688 case dOPENSHUTTER:
5689 1694 doortype=dt_osht;
5690 1694 break;
5691
5692 case dBOSS:
5693 172 doortype=dt_boss;
5694 172 break;
5695
5696 case dOPENBOSS:
5697 67 doortype=dt_obos;
5698 67 break;
5699
5700 case dBOMBED:
5701 1138 doortype=dt_bomb;
5702 1138 break;
5703
5704 default:
5705 655 return;
5706 }
5707
5708
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5111 times.
✓ Branch 4 taken 5230 times.
21740 switch(side)
5709 {
5710 case up:
5711 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5712 5629 break;
5713
5714 case down:
5715 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5716 5770 break;
5717
5718 case left:
5719 5111 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5720 5111 break;
5721
5722 case right:
5723 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5724 5230 break;
5725 }
5726 47568 }
5727
5728 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5729 {
5730 /*
5731 #define dWALL 0 // 000 0
5732 #define dBOMB 6 // 011 0
5733 #define 8 // 100 0
5734 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5735 */
5736
5737
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5738 91 return;
5739
5740 int32_t doortype;
5741
5742
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5743 {
5744 case dWALL:
5745 doortype=dt_wall;
5746 break;
5747
5748 case dWALK:
5749 doortype=dt_walk;
5750 break;
5751
5752 case dOPEN:
5753 50 doortype=dt_pass;
5754 50 break;
5755
5756 case dLOCKED:
5757 doortype=dt_lock;
5758 break;
5759
5760 case dUNLOCKED:
5761 362 doortype=dt_olck;
5762 362 break;
5763
5764 case dSHUTTER:
5765
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5766 {
5767 doortype=dt_osht;
5768 get_screen_state(cur_screen).open_doors = -4;
5769 break;
5770 }
5771
5772 [[fallthrough]];
5773 case d1WAYSHUTTER:
5774 1757 doortype=dt_shut;
5775 1757 break;
5776
5777 case dOPENSHUTTER:
5778 3958 doortype=dt_osht;
5779 3958 break;
5780
5781 case dBOSS:
5782 4 doortype=dt_boss;
5783 4 break;
5784
5785 case dOPENBOSS:
5786 51 doortype=dt_obos;
5787 51 break;
5788
5789 case dBOMBED:
5790 231 doortype=dt_bomb;
5791 231 break;
5792
5793 default:
5794 return;
5795 }
5796
5797
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5798 {
5799 case up:
5800
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5801 {
5802 case dBOMBED:
5803
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5804 {
5805 69 over_door(scr,dest,39,side,0,0);
5806 69 }
5807 [[fallthrough]];
5808 default:
5809 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5810 1860 break;
5811 }
5812
5813 1860 break;
5814
5815 case down:
5816
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5817 {
5818 case dBOMBED:
5819
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5820 {
5821 39 over_door(scr,dest,135,side,0,0);
5822 39 }
5823 [[fallthrough]];
5824 default:
5825 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5826 1357 break;
5827 }
5828
5829 1357 break;
5830
5831 case left:
5832
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5833 {
5834 case dBOMBED:
5835
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5836 {
5837 51 over_door(scr,dest,66,side,0,0);
5838 51 }
5839 [[fallthrough]];
5840 default:
5841 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5842 1514 break;
5843 }
5844
5845 1514 break;
5846
5847 case right:
5848
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5849 {
5850 case dBOMBED:
5851
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5852 {
5853 72 over_door(scr,dest,77,side,0,0);
5854 72 }
5855 [[fallthrough]];
5856 default:
5857 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5858 1682 break;
5859 }
5860
5861 1682 break;
5862 }
5863 6504 }
5864
5865 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5866 {
5867
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5868 {
5869 586 putcombo(dest,x, y, combo, cset);
5870 586 }
5871 586 }
5872
5873 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5874 {
5875
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5876 {
5877 219 overcombo(dest,x, y, combo, cset);
5878 219 }
5879 293 }
5880
5881 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5882 {
5883 125 int32_t d = scr->door_combo_set;
5884
5885
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5886 {
5887 case up:
5888 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5889 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5890 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5891 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5892 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5893 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5894 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5895 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5896 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5897 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5898 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5899 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5900 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5901 43 DoorComboSets[d].bombdoorcombo_u[0],
5902 43 DoorComboSets[d].bombdoorcset_u[0]);
5903 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5904 43 DoorComboSets[d].bombdoorcombo_u[1],
5905 43 DoorComboSets[d].bombdoorcset_u[1]);
5906 43 break;
5907
5908 case down:
5909 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5910 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5911 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5912 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5913 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5914 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5915 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5916 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5917 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5918 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5919 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5920 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5921 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5922 39 DoorComboSets[d].bombdoorcombo_d[0],
5923 39 DoorComboSets[d].bombdoorcset_d[0]);
5924 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5925 39 DoorComboSets[d].bombdoorcombo_d[1],
5926 39 DoorComboSets[d].bombdoorcset_d[1]);
5927 39 break;
5928
5929 case left:
5930 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5931 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5932 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5933 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5934 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5935 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5936 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5937 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5938 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5939 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5940 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5941 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5942 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5943 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5944 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5945 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5946 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5947 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5948 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5949 6 DoorComboSets[d].bombdoorcombo_l[0],
5950 6 DoorComboSets[d].bombdoorcset_l[0]);
5951 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5952 6 DoorComboSets[d].bombdoorcombo_l[1],
5953 6 DoorComboSets[d].bombdoorcset_l[1]);
5954 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5955 6 DoorComboSets[d].bombdoorcombo_l[2],
5956 6 DoorComboSets[d].bombdoorcset_l[2]);
5957 6 break;
5958
5959 case right:
5960 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5961 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5962 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5963 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5964 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5965 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5966 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5967 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5968 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5969 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5970 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5971 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5972 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5973 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5974 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5975 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5976 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5977 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5978 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5979 37 DoorComboSets[d].bombdoorcombo_r[0],
5980 37 DoorComboSets[d].bombdoorcset_r[0]);
5981 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5982 37 DoorComboSets[d].bombdoorcombo_r[1],
5983 37 DoorComboSets[d].bombdoorcset_r[1]);
5984 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5985 37 DoorComboSets[d].bombdoorcombo_r[2],
5986 37 DoorComboSets[d].bombdoorcset_r[2]);
5987 37 break;
5988 }
5989 125 }
5990
5991 5527836 void openshutters(mapscr* scr)
5992 {
5993 5527836 bool opened_door = false;
5994
2/2
✓ Branch 0 taken 5527836 times.
✓ Branch 1 taken 22111344 times.
27639180 for(int32_t i=0; i<4; i++)
5995
2/2
✓ Branch 0 taken 22107386 times.
✓ Branch 1 taken 3958 times.
22115302 if(scr->door[i]==dSHUTTER)
5996 {
5997 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5998 3958 scr->door[i]=dOPENSHUTTER;
5999 3958 opened_door = true;
6000 3958 }
6001
6002 5527836 auto& combo_cache = combo_caches::shutter;
6003 2222068418 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
6004
3/4
✓ Branch 0 taken 2214618025 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1922550 times.
✗ Branch 3 not taken.
2216540582 if (!combo_cache.minis[handle.data()].shutter)
6005 2216540575 return;
6006
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
6007 7 return trig.trigger_flags.get(TRIGFLAG_SHUTTER);
6008 });
6009 2216540582 });
6010
6011
2/2
✓ Branch 0 taken 5525105 times.
✓ Branch 1 taken 2731 times.
5527836 if(opened_door)
6012 2731 sfx(WAV_DOOR);
6013 5527836 }
6014
6015 15711048 void clear_darkroom_bitmaps()
6016 {
6017 15711048 clear_to_color(darkscr_bmp, game->get_darkscr_color());
6018 15711048 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
6019 15711048 }
6020
6021 16738950 bool is_dark(const mapscr* scr)
6022 {
6023 16738950 bool dark = scr->flags&fDARK;
6024
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16735228 times.
16738950 if (region_is_lit) return !dark;
6025 16735228 return dark;
6026 16738950 }
6027
6028 53189 bool scrolling_is_dark(const mapscr* scr)
6029 {
6030 53189 bool dark = scr->flags&fDARK;
6031
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 53187 times.
53189 if (scrolling_region_is_lit) return !dark;
6032 53187 return dark;
6033 53189 }
6034
6035 38432 bool is_any_dark()
6036 {
6037 38432 bool dark = false;
6038 78120 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
6039 39688 dark |= (bool)(is_dark(scr));
6040 39688 });
6041 38432 return dark;
6042 }
6043
6044
3/4
✓ Branch 0 taken 2975 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2550 times.
✓ Branch 3 taken 425 times.
2975 static mapscr prev_origin_scrs[7];
6045 425 static std::set<int> loadscr_ffc_script_ids_to_remove;
6046
6047 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
6048 {
6049 mapscr* base_scr = screens[0];
6050 mapscr* previous_scr = &prev_origin_scrs[0];
6051
6052 for (int i = 0; i < 176; i++)
6053 {
6054 if (base_scr->data[i] == 0)
6055 {
6056 base_scr->data[i] = previous_scr->data[i];
6057 base_scr->sflag[i] = previous_scr->sflag[i];
6058 base_scr->cset[i] = previous_scr->cset[i];
6059 }
6060 }
6061
6062 for (int i = 0; i < 6; i++)
6063 {
6064 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
6065 {
6066 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
6067 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
6068
6069 for (int j = 0; j < 176; j++)
6070 {
6071 if (TheMaps[lm].data[j] == 0)
6072 {
6073 TheMaps[lm].data[j] = TheMaps[fm].data[j];
6074 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
6075 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
6076 }
6077 }
6078 }
6079 }
6080
6081 for (int i = 1; i <= 6; i++)
6082 {
6083 mapscr* scr = screens[i];
6084 previous_scr = &prev_origin_scrs[i];
6085
6086 if (scr->layermap[i] > 0)
6087 {
6088 for (int y = 0; y < 11; y++)
6089 {
6090 for (int x = 0; x < 16; x++)
6091 {
6092 int c = y*16+x;
6093
6094 if (scr->data[c]==0)
6095 {
6096 scr->data[c] = previous_scr->data[c];
6097 scr->sflag[c] = previous_scr->sflag[c];
6098 scr->cset[c] = previous_scr->cset[c];
6099 }
6100 }
6101 }
6102 }
6103 }
6104 }
6105
6106 38772 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
6107 {
6108 38772 std::vector<mapscr*> screens;
6109
6110
1/2
✓ Branch 0 taken 38772 times.
✗ Branch 1 not taken.
38772 const mapscr* source = get_canonical_scr(cur_map, screen);
6111
2/4
✓ Branch 0 taken 38772 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38772 times.
✗ Branch 3 not taken.
38772 mapscr* base_scr = new mapscr(*source);
6112 38772 temporary_screens[screen*7] = base_scr;
6113
1/2
✓ Branch 0 taken 38772 times.
✗ Branch 1 not taken.
38772 screens.push_back(base_scr);
6114
6115 38772 base_scr->valid |= mVALID; // layer 0 is always valid
6116
6117
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 37528 times.
38772 if (screen == cur_screen)
6118 37528 origin_scr = base_scr;
6119
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 37528 times.
38772 if (screen == Hero.current_screen)
6120 37528 hero_scr = prev_hero_scr = base_scr;
6121
6122
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 38628 times.
38772 if (source->script > 0)
6123
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6124
6125
2/2
✓ Branch 0 taken 38772 times.
✓ Branch 1 taken 232632 times.
271404 for (int i = 0; i < 6; i++)
6126 {
6127
2/2
✓ Branch 0 taken 176163 times.
✓ Branch 1 taken 56469 times.
232632 if(source->layermap[i]>0)
6128 {
6129
3/6
✓ Branch 0 taken 56469 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56469 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56469 times.
✗ Branch 5 not taken.
56469 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
6130 56469 layer_scr->map = cur_map;
6131 56469 layer_scr->screen = screen;
6132 56469 layer_scr->valid |= mVALID;
6133
1/2
✓ Branch 0 taken 56469 times.
✗ Branch 1 not taken.
56469 screens.push_back(layer_scr);
6134 56469 }
6135 else
6136 {
6137
2/4
✓ Branch 0 taken 176163 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 176163 times.
✗ Branch 3 not taken.
176163 mapscr* layer_scr = new mapscr();
6138 176163 layer_scr->map = cur_map;
6139 176163 layer_scr->screen = screen;
6140
1/2
✓ Branch 0 taken 176163 times.
✗ Branch 1 not taken.
176163 screens.push_back(layer_scr);
6141 }
6142 232632 temporary_screens[screen*7+i+1] = screens[i+1];
6143 232632 }
6144
6145
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 38772 times.
38772 if (screen_overlay)
6146 handle_screen_overlay(screens);
6147
6148
2/2
✓ Branch 0 taken 145 times.
✓ Branch 1 taken 38627 times.
38772 if (ffc_overlay)
6149 {
6150 145 mapscr* previous_scr = &prev_origin_scrs[0];
6151
1/2
✓ Branch 0 taken 145 times.
✗ Branch 1 not taken.
145 int num_ffcs = previous_scr->numFFC();
6152
2/2
✓ Branch 0 taken 4640 times.
✓ Branch 1 taken 145 times.
4785 for (int i = 0; i < num_ffcs; i++)
6153 {
6154
2/2
✓ Branch 0 taken 4365 times.
✓ Branch 1 taken 275 times.
4640 if ((previous_scr->ffcs[i].flags&ffc_carryover))
6155 {
6156
2/4
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 275 times.
✗ Branch 3 not taken.
275 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
6157 275 ffc.screen_spawned = screen;
6158
6159
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
6160
1/2
✓ Branch 0 taken 275 times.
✗ Branch 1 not taken.
275 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
6161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 275 times.
275 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
6162 {
6163 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
6164 }
6165 275 }
6166 4640 }
6167 145 }
6168
6169
1/2
✓ Branch 0 taken 38772 times.
✗ Branch 1 not taken.
1145563 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6170
1/2
✓ Branch 0 taken 38772 times.
✗ Branch 1 not taken.
38772 int num_ffcs = base_scr->numFFC();
6171
2/2
✓ Branch 0 taken 1106791 times.
✓ Branch 1 taken 38772 times.
1145563 for (word i = 0; i < num_ffcs; i++)
6172 {
6173 1106791 base_scr->ffcs[i].screen_spawned = screen;
6174
1/2
✓ Branch 0 taken 1106791 times.
✗ Branch 1 not taken.
1106791 base_scr->ffcs[i].x += offx;
6175
1/2
✓ Branch 0 taken 1106791 times.
✗ Branch 1 not taken.
1106791 base_scr->ffcs[i].y += offy;
6176 1106791 }
6177 38772 }
6178
6179 38772 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
6180 {
6181 38772 mapscr* base_scr = get_scr(screen);
6182 38772 int mi = mapind(cur_map, screen);
6183
6184 // Apply perm secrets, if applicable.
6185
2/2
✓ Branch 0 taken 11520 times.
✓ Branch 1 taken 27252 times.
38772 if (canPermSecret(dmap, screen))
6186 {
6187
2/2
✓ Branch 0 taken 24346 times.
✓ Branch 1 taken 2906 times.
27252 if(game->maps[mi] & mSECRET) // if special stuff done before
6188 {
6189 2906 reveal_hidden_stairs(base_scr, screen, false);
6190 2906 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
6191 2906 }
6192
2/2
✓ Branch 0 taken 27249 times.
✓ Branch 1 taken 3 times.
27252 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
6193 {
6194
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
6195 {
6196 21 mapscr* layer_scr = get_scr_layer(screen, layer);
6197
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
6198 {
6199 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
6200
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
6201 {
6202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
6203 {
6204 3 layer_scr->data[pos] += 1;
6205 3 }
6206 3 }
6207 3696 }
6208 21 }
6209 3 }
6210 27252 }
6211
6212 38772 auto screen_handles = create_screen_handles(base_scr);
6213
6214 38772 int destlvl = DMaps[dmap].level;
6215 38772 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6216 38772 toggle_gswitches_load(screen_handles);
6217
6218 38772 bool should_check_for_state_things = (screen < 0x80);
6219
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 37865 times.
38772 if (should_check_for_state_things)
6220 {
6221
2/2
✓ Branch 0 taken 37431 times.
✓ Branch 1 taken 434 times.
37865 if (game->maps[mi]&mLOCKBLOCK)
6222 434 remove_lockblocks(screen_handles);
6223
2/2
✓ Branch 0 taken 37776 times.
✓ Branch 1 taken 89 times.
37865 if (game->maps[mi]&mBOSSLOCKBLOCK)
6224 89 remove_bosslockblocks(screen_handles);
6225
2/2
✓ Branch 0 taken 37697 times.
✓ Branch 1 taken 168 times.
37865 if (game->maps[mi]&mCHEST)
6226 168 remove_chests(screen_handles);
6227
1/2
✓ Branch 0 taken 37865 times.
✗ Branch 1 not taken.
37865 if (game->maps[mi]&mLOCKEDCHEST)
6228 remove_lockedchests(screen_handles);
6229
2/2
✓ Branch 0 taken 37854 times.
✓ Branch 1 taken 11 times.
37865 if (game->maps[mi]&mBOSSCHEST)
6230 11 remove_bosschests(screen_handles);
6231
6232 37865 clear_xdoors_mi(screen_handles, mi, true);
6233 37865 clear_xstatecombos_mi(screen_handles, mi, true);
6234 37865 }
6235
6236 // check doors
6237
2/2
✓ Branch 0 taken 27251 times.
✓ Branch 1 taken 11521 times.
38772 if (isdungeon(dmap, screen))
6238 {
6239
2/2
✓ Branch 0 taken 46084 times.
✓ Branch 1 taken 11521 times.
57605 for(int32_t i=0; i<4; i++)
6240 {
6241 46084 int32_t door=base_scr->door[i];
6242
6243
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36475 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46084 switch(door)
6244 {
6245 case d1WAYSHUTTER:
6246 case dSHUTTER:
6247
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == Hero.current_screen)
6248 {
6249 1694 base_scr->door[i]=dOPENSHUTTER;
6250 1694 }
6251
6252 5303 get_screen_state(screen).open_doors = -4;
6253 5303 break;
6254
6255 case dLOCKED:
6256
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6257 {
6258 1473 base_scr->door[i]=dUNLOCKED;
6259 1473 }
6260
6261 2372 break;
6262
6263 case dBOSS:
6264
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6265 {
6266 62 base_scr->door[i]=dOPENBOSS;
6267 62 }
6268
6269 230 break;
6270
6271 case dBOMB:
6272
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6273 {
6274 1087 base_scr->door[i]=dBOMBED;
6275 1087 }
6276
6277 1704 break;
6278 }
6279
6280 46084 update_door(base_scr, i, base_scr->door[i]);
6281
6282
4/4
✓ Branch 0 taken 41517 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40781 times.
46084 if(door==dSHUTTER||door==d1WAYSHUTTER)
6283 {
6284 5303 base_scr->door[i]=door;
6285 5303 }
6286 46084 }
6287 11521 }
6288
6289
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 38633 times.
38772 if (!(base_scr->flags3 & fCYCLEONINIT))
6290 38633 return;
6291
6292
2/2
✓ Branch 0 taken 139 times.
✓ Branch 1 taken 973 times.
1112 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6293 {
6294
4/4
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 139 times.
✓ Branch 2 taken 383 times.
✓ Branch 3 taken 451 times.
973 if (j<0 || base_scr->layermap[j] > 0)
6295 {
6296 522 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6297
3/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 139 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 383 times.
522 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6298 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6299
6300
2/2
✓ Branch 0 taken 91872 times.
✓ Branch 1 taken 522 times.
92394 for(int32_t i=0; i<176; ++i)
6301 {
6302 91872 int32_t c=layerscreen->data[i];
6303
6304 // New screen flag: Cycle Combos At Screen Init
6305
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 91807 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
91872 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6306 {
6307 65 int32_t r = 0;
6308
6309
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6310 {
6311 84 newcombo const& cmb = combobuf[c];
6312 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6313
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6314 84 layerscreen->data[i] = cid;
6315
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6316
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6317 84 c = layerscreen->data[i];
6318 }
6319 65 }
6320 91872 }
6321 522 }
6322 973 }
6323 38772 }
6324
6325 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6326 //
6327 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6328 // the game, etc...)
6329 //
6330 // Note: for regions, only the initial screen load calls this function. Simply walking between
6331 // screens in the same region does not use this, because every screen in a region is loaded into
6332 // temporary memory up front.
6333 //
6334 // If scr >= 0x80, `Hero.current_screen` will be saved to `home_screen` and also be loaded into
6335 // `special_warp_return_scr`.
6336 //
6337 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6338 // on all layers (but only where the new screen has a 0 combo).
6339 //
6340 // TODO: loadscr should set curdmap, but currently callers do that.
6341 37528 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6342 {
6343 37528 zapp_reporting_set_tag("screen", screen);
6344
2/2
✓ Branch 0 taken 9308 times.
✓ Branch 1 taken 28220 times.
37528 if (destdmap != -1)
6345 9308 zapp_reporting_set_tag("dmap", destdmap);
6346
6347 37528 int32_t orig_destdmap = destdmap;
6348
2/2
✓ Branch 0 taken 9308 times.
✓ Branch 1 taken 28220 times.
37528 if (destdmap < 0) destdmap = cur_dmap;
6349
6350
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37528 times.
37528 if (replay_is_active())
6351 {
6352
2/2
✓ Branch 0 taken 28220 times.
✓ Branch 1 taken 9308 times.
37528 if (orig_destdmap != -1)
6353 {
6354
2/2
✓ Branch 0 taken 8237 times.
✓ Branch 1 taken 1071 times.
9308 if (strlen(DMaps[orig_destdmap].name) > 0)
6355 {
6356
1/2
✓ Branch 0 taken 8237 times.
✗ Branch 1 not taken.
8237 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6357 8237 }
6358 else
6359 {
6360
1/2
✓ Branch 0 taken 1071 times.
✗ Branch 1 not taken.
1071 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6361 }
6362 9308 }
6363 37528 replay_step_comment_loadscr(screen);
6364
6365 // Reset the rngs and frame count so that recording steps can be modified without impacting
6366 // behavior of later screens.
6367 37528 replay_sync_rng();
6368 37528 }
6369
6370
2/2
✓ Branch 0 taken 1754087 times.
✓ Branch 1 taken 37528 times.
1791615 for (auto& state : get_screen_states())
6371 1754087 state.second.triggered_secrets = false;
6372 37528 slopes.clear();
6373 37528 Hero.clear_platform_ffc();
6374 37528 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6375 37528 clear_darkroom_bitmaps();
6376 37528 msgscr = nullptr;
6377
6378
2/2
✓ Branch 0 taken 52507598 times.
✓ Branch 1 taken 37528 times.
52545126 for (word x=0; x<animated_combos; x++)
6379 {
6380
2/2
✓ Branch 0 taken 21102274 times.
✓ Branch 1 taken 31405324 times.
52507598 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6381 {
6382 21102274 combobuf[animated_combo_table4[x][0]].aclk = 0;
6383 21102274 }
6384 52507598 }
6385 37528 reset_combo_animations2();
6386 37528 region_is_lit = false;
6387
6388 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6389 // of the new ones.
6390 37528 bool origin_ffc_overlay = false;
6391
2/2
✓ Branch 0 taken 1168 times.
✓ Branch 1 taken 36360 times.
37528 if (origin_scr)
6392 {
6393
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 36358 times.
36360 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6394 {
6395 36358 int c = origin_scr->numFFC();
6396
2/2
✓ Branch 0 taken 36213 times.
✓ Branch 1 taken 1040673 times.
1076886 for (int i = 0; i < c; i++)
6397 {
6398
2/2
✓ Branch 0 taken 1040528 times.
✓ Branch 1 taken 145 times.
1040673 if (origin_scr->ffcs[i].flags&ffc_carryover)
6399 {
6400 145 origin_ffc_overlay = true;
6401 145 break;
6402 }
6403 1040528 }
6404 36358 }
6405
6406
3/4
✓ Branch 0 taken 36360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 145 times.
✓ Branch 3 taken 36215 times.
36360 if (origin_screen_overlay || origin_ffc_overlay)
6407 {
6408
2/2
✓ Branch 0 taken 1015 times.
✓ Branch 1 taken 145 times.
1160 for (int i = 0; i <= 6; i++)
6409 {
6410 1015 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6411
1/2
✓ Branch 0 taken 1015 times.
✗ Branch 1 not taken.
1015 if (prev_scr)
6412 1015 prev_origin_scrs[i] = *prev_scr;
6413 else
6414 prev_origin_scrs[i] = {};
6415 1015 }
6416 145 }
6417 36360 }
6418
6419 // When loading a new screen, all previous FFC scripts end, with one exception.
6420 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6421 // them, but scripts that need their data to persist will be removed.
6422 37528 loadscr_ffc_script_ids_to_remove.clear();
6423
2/2
✓ Branch 0 taken 83197316 times.
✓ Branch 1 taken 37528 times.
83234844 for (auto& key : scriptEngineDatas | std::views::keys)
6424 {
6425
2/2
✓ Branch 0 taken 82066363 times.
✓ Branch 1 taken 1130953 times.
83197316 if (key.first == ScriptType::FFC)
6426 1130953 loadscr_ffc_script_ids_to_remove.insert(key.second);
6427 }
6428
6429 37528 load_region(destdmap, screen);
6430
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36621 times.
37528 home_screen = screen >= 0x80 ? Hero.current_screen : cur_screen;
6431 37528 Hero.current_screen = screen;
6432
6433 37528 cpos_clear_all();
6434 37528 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6435 37528 FFCore.clear_combo_scripts();
6436
6437
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 37364 times.
37528 if (is_in_scrolling_region())
6438 {
6439
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6440 {
6441
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6442 {
6443
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6444
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6445 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6446 1408 }
6447 20992 }
6448 164 }
6449 else
6450 {
6451 37364 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6452 }
6453
6454 37528 prepare_current_region_handles();
6455
6456
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 37364 times.
37528 if (is_in_scrolling_region())
6457 {
6458
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6459 {
6460
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6461 {
6462 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6463 1408 }
6464 20992 }
6465 164 }
6466 else
6467 {
6468 37364 load_a_screen_and_layers_post(destdmap, screen, ldir);
6469 }
6470
6471 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6472
2/2
✓ Branch 0 taken 36621 times.
✓ Branch 1 taken 907 times.
37528 if (screen >= 0x80)
6473
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6474
6475 37528 update_slope_comboposes();
6476 37528 cpos_force_update();
6477 37528 trig_trigger_groups();
6478
6479
2/2
✓ Branch 0 taken 1130678 times.
✓ Branch 1 taken 37528 times.
1168206 for (int index : loadscr_ffc_script_ids_to_remove)
6480 {
6481 // Note: ideally would use "destroySprite", but during scrolling the previous
6482 // screen's FFCs are still accessible (even though only the new screen's FFC scripts run).
6483 // The only difference is a call to "release_sprite_owned_objects". To defer FFC script
6484 // owned objects being released until the end of the scroll, here "destroyScriptableObject"
6485 // is used instead.
6486 //
6487 // So when is "release_sprite_owned_objects" called for FFCs? For scrolling screen
6488 // transitions, it's at the end of "scrollscr" via "delete_temporary_screens". Otherwise,
6489 // it is called above when "load_region" calls "clear_temporary_screens".
6490 1130678 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6491 }
6492
6493 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6494 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6495 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6496 // It is up to the quest designer to make their subscreen be actually transparent.
6497 //
6498 // When not in "extended height mode" (otherwise 56 is 0):
6499 // - playing_field_offset: 56, but changes during earthquakes
6500 // - original_playing_field_offset: always 56
6501 //
6502 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6503 // - yofs of sprites
6504 // - bitmap y offsets in draw_screen
6505 // - drawing offsets for putscr, do_layer
6506 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6507 // - lots more
6508 //
6509 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6510
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 37386 times.
37528 if (is_extended_height_mode())
6511 {
6512 142 playing_field_offset = 0;
6513 142 original_playing_field_offset = 0;
6514 // A few sprites exist as globals, so we must manually reset them.
6515 142 Hero.yofs = 0;
6516 142 mblock2.yofs = 0;
6517 142 }
6518 else
6519 {
6520 37386 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6521 37386 original_playing_field_offset = 56;
6522 }
6523 37528 is_any_room_dark = is_any_dark();
6524
6525 37528 game->load_portal();
6526 37528 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6527
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 37493 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
37528 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6528 {
6529 delete Hero.lift_wpn;
6530 Hero.lift_wpn = nullptr;
6531 }
6532
6533 37528 enemy_spawning_has_checked_been_here = false;
6534 37528 markBmap(-1, Hero.current_screen);
6535 37528 Hero.maybe_begin_advanced_maze();
6536 37528 }
6537
6538 // Don't use this directly! Use `loadscr` instead.
6539 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6540 {
6541
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6542
6543 907 mapscr previous_scr = *special_warp_return_scr;
6544 907 mapscr* scr = special_warp_return_scr;
6545
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6546
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6547
6548
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6549 {
6550
2/2
✓ Branch 0 taken 5059 times.
✓ Branch 1 taken 383 times.
5442 if (scr->layermap[i-1] > 0)
6551
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6552 else
6553
2/4
✓ Branch 0 taken 5059 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5059 times.
✗ Branch 3 not taken.
5059 special_warp_return_scrs[i] = {};
6554 5442 }
6555
6556 907 scr->valid |= mVALID; //layer 0 is always valid
6557
6558
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6559 {
6560 scr->script = source->script;
6561 for ( int32_t q = 0; q < 8; q++ )
6562 {
6563 scr->screeninitd[q] = source->screeninitd[q];
6564 }
6565 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6566 }
6567 else
6568 {
6569 907 scr->script = 0;
6570 }
6571
6572
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6573 {
6574 for(int32_t c=0; c< 176; ++c)
6575 {
6576 if(scr->data[c]==0)
6577 {
6578 scr->data[c]=previous_scr.data[c];
6579 scr->sflag[c]=previous_scr.sflag[c];
6580 scr->cset[c]=previous_scr.cset[c];
6581 }
6582 }
6583
6584 for(int32_t i=0; i<6; i++)
6585 {
6586 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6587 {
6588 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6589 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6590
6591 for(int32_t c=0; c< 176; ++c)
6592 {
6593 if(TheMaps[lm].data[c]==0)
6594 {
6595 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6596 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6597 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6598 }
6599 }
6600 }
6601 }
6602 }
6603
6604
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6605
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6606
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6607 {
6608 28993 scr->ffcs[i].screen_spawned = screen;
6609
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6610
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6611 28993 }
6612
6613 907 int mi = mapind(cur_map, screen);
6614
6615 // Apply perm secrets, if applicable.
6616
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6617 {
6618
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6619 {
6620
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6621
6622
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6623
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6624 204 bool do_replay_comment = true;
6625 204 bool from_active_screen = false;
6626
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6627 204 }
6628
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6629 {
6630 for (int layer = 0; layer <= 6; layer++)
6631 {
6632 mapscr* tscr = &special_warp_return_scrs[layer];
6633 for (int pos = 0; pos < 176; pos++)
6634 {
6635 newcombo const* cmb = &combobuf[tscr->data[pos]];
6636 if(cmb->type == cLIGHTTARGET)
6637 {
6638 if(!(cmb->usrflags&cflag1)) //Unlit version
6639 {
6640 tscr->data[pos] += 1;
6641 }
6642 }
6643 }
6644 }
6645 }
6646 536 }
6647
6648 screen_handles_t screen_handles;
6649
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6650
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1284 times.
✓ Branch 3 taken 5065 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6651
6652
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6653
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6654
6655
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6656 {
6657
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6658 5 }
6659
6660
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6661 {
6662
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6663 1 }
6664
6665
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6666 {
6667 remove_chests(screen_handles);
6668 }
6669
6670
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6671 {
6672 remove_lockedchests(screen_handles);
6673 }
6674
6675
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6676 {
6677 remove_bosschests(screen_handles);
6678 }
6679
6680
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6681
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6682
6683 // check doors
6684
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if (isdungeon(destdmap, screen))
6685 {
6686
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6687 {
6688 1484 int32_t door=scr->door[i];
6689
6690
4/5
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1295 times.
1484 switch(door)
6691 {
6692 case d1WAYSHUTTER:
6693 case dSHUTTER:
6694 if ((ldir^1)==i && screen == home_screen)
6695 {
6696 scr->door[i]=dOPENSHUTTER;
6697 }
6698
6699 get_screen_state(screen).open_doors = -4;
6700 105 break;
6701
6702 case dLOCKED:
6703
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 80 times.
91 if(game->maps[mi]&(mDOOR_UP<<i))
6704 {
6705 80 scr->door[i]=dUNLOCKED;
6706 80 }
6707
6708 91 break;
6709
6710 case dBOSS:
6711
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 5 times.
9 if(game->maps[mi]&(mDOOR_UP<<i))
6712 {
6713 5 scr->door[i]=dOPENBOSS;
6714 5 }
6715
6716 9 break;
6717
6718 case dBOMB:
6719
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 51 times.
89 if(game->maps[mi]&(mDOOR_UP<<i))
6720 {
6721 51 scr->door[i]=dBOMBED;
6722 51 }
6723
6724 89 break;
6725 }
6726
6727
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 105 times.
1589 update_door(scr, i, scr->door[i]);
6728
6729
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6730 {
6731 105 scr->door[i]=door;
6732 105 }
6733 1484 }
6734 371 }
6735
6736
2/2
✓ Branch 0 taken 6139 times.
✓ Branch 1 taken 1117 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6737 {
6738
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 697 times.
✓ Branch 2 taken 593 times.
✓ Branch 3 taken 4849 times.
6139 if (j<0 || scr->layermap[j] > 0)
6739 {
6740
4/4
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 907 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
1290 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6741 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6742
6743
2/2
✓ Branch 0 taken 226830 times.
✓ Branch 1 taken 1500 times.
228330 for(int32_t i=0; i<176; ++i)
6744 {
6745 226830 int32_t c=layerscreen->data[i];
6746
6747 // New screen flag: Cycle Combos At Screen Init
6748
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 226824 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 210 times.
✓ Branch 7 taken 210 times.
226830 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6749 {
6750 210 int32_t r = 0;
6751
6752
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 210 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
210 while(combobuf[c].can_cycle() && r++ < 10)
6753 {
6754 newcombo const& cmb = combobuf[c];
6755 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6756 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6757 layerscreen->data[i] = cid;
6758 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6759 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6760 c = layerscreen->data[i];
6761 }
6762 }
6763 227040 }
6764 1500 }
6765 6349 }
6766 1537 }
6767
6768 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6769 // instead returns an array of mapscr.
6770 // Used to draw/save the map.
6771 47360 std::array<mapscr, 7> loadscr2(int32_t screen)
6772 {
6773 47360 std::array<mapscr, 7> scrs;
6774 47360 mapscr* scr = &scrs[0];
6775
6776
2/2
✓ Branch 0 taken 66834661 times.
✓ Branch 1 taken 47360 times.
66882021 for(word x=0; x<animated_combos; x++)
6777 {
6778
2/2
✓ Branch 0 taken 33899045 times.
✓ Branch 1 taken 32935616 times.
66834661 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6779 {
6780 32935616 combobuf[animated_combo_table4[x][0]].aclk=0;
6781 32935616 }
6782 66834661 }
6783
6784
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 const mapscr* source = get_canonical_scr(cur_map, screen);
6785
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if (!source->is_valid())
6786 {
6787 scrs[0].valid = 0;
6788 return scrs;
6789 }
6790
6791
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 *scr = *get_canonical_scr(cur_map, screen);
6792
2/2
✓ Branch 0 taken 284160 times.
✓ Branch 1 taken 47360 times.
331520 for (int i = 1; i <= 6; i++)
6793 {
6794
2/2
✓ Branch 0 taken 209501 times.
✓ Branch 1 taken 74659 times.
284160 if (scr->layermap[i-1] > 0)
6795
2/4
✓ Branch 0 taken 74659 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 74659 times.
✗ Branch 3 not taken.
74659 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6796 else
6797
2/4
✓ Branch 0 taken 209501 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 209501 times.
✗ Branch 3 not taken.
209501 scrs[i] = {};
6798 284160 }
6799
6800 screen_handles_t screen_handles;
6801
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 331520 times.
378880 for (int i = 0; i < 7; i++)
6802
3/4
✓ Branch 0 taken 331520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114582 times.
✓ Branch 3 taken 216938 times.
331520 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6803
6804 47360 int mi = mapind(cur_map, screen);
6805
6806
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47306 times.
✓ Branch 3 taken 54 times.
47360 if(canPermSecret(-1,screen))
6807 {
6808
3/4
✓ Branch 0 taken 47306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6344 times.
✓ Branch 3 taken 40962 times.
47306 if(game->maps[mi]&mSECRET) // if special stuff done before
6809 {
6810
1/2
✓ Branch 0 taken 6344 times.
✗ Branch 1 not taken.
6344 reveal_hidden_stairs(scr, screen, false);
6811 6344 bool from_active_screen = false;
6812 6344 bool do_replay_comment = true;
6813
1/2
✓ Branch 0 taken 6344 times.
✗ Branch 1 not taken.
6344 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6814 6344 }
6815
3/4
✓ Branch 0 taken 47306 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47289 times.
✓ Branch 3 taken 17 times.
47306 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6816 {
6817
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6818 {
6819 119 mapscr* tscr = &scrs[layer];
6820
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6821 {
6822 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6823
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6824 {
6825
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6826 {
6827 17 tscr->data[pos] += 1;
6828 17 }
6829 17 }
6830 20944 }
6831 119 }
6832 17 }
6833 47306 }
6834
6835
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 271 times.
✓ Branch 3 taken 47089 times.
47360 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6836 {
6837
1/2
✓ Branch 0 taken 271 times.
✗ Branch 1 not taken.
271 remove_lockblocks(screen_handles);
6838 271 }
6839
6840
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 47359 times.
47360 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6841 {
6842
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6843 1 }
6844
6845
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106 times.
✓ Branch 3 taken 47254 times.
47360 if(game->maps[mi]&mCHEST) // if special stuff done before
6846 {
6847
1/2
✓ Branch 0 taken 106 times.
✗ Branch 1 not taken.
106 remove_chests(screen_handles);
6848 106 }
6849
6850
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 47336 times.
47360 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6851 {
6852
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6853 24 }
6854
6855
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 47360 times.
47360 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6856 {
6857 remove_bosschests(screen_handles);
6858 }
6859
6860
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 clear_xdoors(screen_handles);
6861
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 clear_xstatecombos(screen_handles);
6862
6863 // check doors
6864
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47306 times.
✓ Branch 3 taken 54 times.
47360 if (isdungeon(screen))
6865 {
6866
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6867 {
6868 216 int32_t door=scr->door[i];
6869 216 bool putit=true;
6870
6871
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6872 {
6873 case d1WAYSHUTTER:
6874 case dSHUTTER:
6875 61 break;
6876
6877 case dLOCKED:
6878
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(mDOOR_UP<<i))
6879 {
6880 12 scr->door[i]=dUNLOCKED;
6881 12 }
6882
6883 12 break;
6884
6885 case dBOSS:
6886
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(mDOOR_UP<<i))
6887 {
6888 scr->door[i]=dOPENBOSS;
6889 }
6890
6891 4 break;
6892
6893 case dBOMB:
6894 if(game->maps[mi]&(mDOOR_UP<<i))
6895 {
6896 scr->door[i]=dBOMBED;
6897 }
6898
6899 break;
6900 }
6901
6902
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6903 {
6904
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6905 216 }
6906
6907
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6908 {
6909 61 scr->door[i]=door;
6910 61 }
6911 216 }
6912 54 }
6913
6914
2/2
✓ Branch 0 taken 331520 times.
✓ Branch 1 taken 47360 times.
378880 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6915 {
6916
4/4
✓ Branch 0 taken 284160 times.
✓ Branch 1 taken 47360 times.
✓ Branch 2 taken 74659 times.
✓ Branch 3 taken 209501 times.
331520 if (j < 0 || scr->layermap[j] > 0)
6917 {
6918
2/2
✓ Branch 0 taken 74659 times.
✓ Branch 1 taken 47360 times.
122019 mapscr *layerscreen= (j<0 ? scr
6919 74659 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6920
6921
2/2
✓ Branch 0 taken 21475344 times.
✓ Branch 1 taken 122019 times.
21597363 for(int32_t i=0; i<176; ++i)
6922 {
6923 21475344 int32_t c=layerscreen->data[i];
6924
6925 // New screen flag: Cycle Combos At Screen Init
6926
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 21475344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
21475344 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6927 {
6928 int32_t r = 0;
6929
6930 while(combobuf[c].can_cycle() && r++ < 10)
6931 {
6932 newcombo const& cmb = combobuf[c];
6933 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6934 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6935 layerscreen->data[i] = cid;
6936 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6937 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6938 c = layerscreen->data[i];
6939 }
6940 }
6941 21475344 }
6942 122019 }
6943 331520 }
6944
6945 47360 return scrs;
6946
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 }
6947
6948 19762741 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6949 {
6950 // This is a bogus value while screenscrolling == true, but that's ok
6951 // because it is only used to calculate the rpos, and during screenscrolling
6952 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6953 // is always the same no matter the value of scr.
6954 19762741 int screen = get_screen_for_world_xy(x, y);
6955
6956 19762741 x -= viewport.x;
6957 19762741 y -= viewport.y;
6958
6959
3/6
✓ Branch 0 taken 19762741 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19762741 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19762741 times.
19762741 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6960 {
6961 rectfill(dest,x,y,x+255,y+175,0);
6962 return;
6963 }
6964
6965 39378015 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6966
2/2
✓ Branch 0 taken 19615274 times.
✓ Branch 1 taken 147467 times.
19762741 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
6967
2/2
✓ Branch 0 taken 243651 times.
✓ Branch 1 taken 19371623 times.
19615274 || !get_qr(qr_CLASSIC_DRAWING_ORDER);
6968
6969 int start_x, end_x, start_y, end_y;
6970 19762741 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6971
2/2
✓ Branch 0 taken 19762741 times.
✓ Branch 1 taken 210488825 times.
230251566 for (int cy = start_y; cy < end_y; cy++)
6972 {
6973
2/2
✓ Branch 0 taken 3195819426 times.
✓ Branch 1 taken 210488825 times.
3406308251 for (int cx = start_x; cx < end_x; cx++)
6974 {
6975 3195819426 int i = cx + cy*16;
6976
2/2
✓ Branch 0 taken 374288294 times.
✓ Branch 1 taken 2821531132 times.
3195819426 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6977 3195819426 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6978 3195819426 }
6979 210488825 }
6980 19762741 }
6981
6982 16128838 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6983 {
6984
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16128838 times.
16128838 if (!show_layers[0])
6985 {
6986 return;
6987 }
6988
6989 16128838 x -= viewport.x;
6990 16128838 y -= viewport.y;
6991
6992
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16128838 times.
32393994 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6993 16265156 mapscr* scr = screen_handles[0].base_scr;
6994
1/2
✓ Branch 0 taken 16265156 times.
✗ Branch 1 not taken.
16265156 if (!scr->is_valid())
6995 return;
6996
6997
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 16141745 times.
16265156 if(scr->door[0]==dBOMBED)
6998 {
6999 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
7000 123411 }
7001
7002
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 16122047 times.
16265156 if(scr->door[1]==dBOMBED)
7003 {
7004 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
7005 143109 }
7006
7007
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 16109294 times.
16265156 if(scr->door[2]==dBOMBED)
7008 {
7009 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
7010 155862 }
7011
7012
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 16132867 times.
16265156 if(scr->door[3]==dBOMBED)
7013 {
7014 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
7015 132289 }
7016 16265156 });
7017 16128838 }
7018
7019 3497585 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
7020 {
7021
2/4
✓ Branch 0 taken 3497585 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3497585 times.
✗ Branch 3 not taken.
3497585 if (!scr->is_valid() || !show_layers[0])
7022 return;
7023
7024 3497585 x -= viewport.x;
7025 3497585 y -= viewport.y;
7026
7027
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3459929 times.
3497585 if(scr->door[0]==dBOMBED)
7028 {
7029 37656 over_door(scr,dest,39,up,x,y);
7030 37656 }
7031
7032
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3461090 times.
3497585 if(scr->door[1]==dBOMBED)
7033 {
7034 36495 over_door(scr,dest,135,down,x,y);
7035 36495 }
7036
7037
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3457145 times.
3497585 if(scr->door[2]==dBOMBED)
7038 {
7039 40440 over_door(scr,dest,66,left,x,y);
7040 40440 }
7041
7042
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3460522 times.
3497585 if(scr->door[3]==dBOMBED)
7043 {
7044 37063 over_door(scr,dest,77,right,x,y);
7045 37063 }
7046 3497585 }
7047 262953820 static inline bool standing_on_z(newcombo const& cmb, zfix const& standing_z_state)
7048 {
7049
1/2
✓ Branch 0 taken 262953820 times.
✗ Branch 1 not taken.
262953820 if (cmb.dive_under_level)
7050 {
7051 if (standing_z_state <= -cmb.dive_under_level)
7052 return true;
7053 }
7054
7055 262953820 zfix cmb_z, cmb_z_step;
7056
4/4
✓ Branch 0 taken 92789 times.
✓ Branch 1 taken 262861031 times.
✓ Branch 2 taken 88819 times.
✓ Branch 3 taken 3970 times.
262953820 if(cmb.type == cCSWITCHBLOCK && (cmb.usrflags & cflag9))
7057 {
7058 3970 cmb_z = zslongToFix(cmb.attributes[2]);
7059
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3970 times.
3970 cmb_z_step = zslongToFix(zc_max(0,cmb.attributes[3]));
7060 3970 }
7061
2/2
✓ Branch 0 taken 1983 times.
✓ Branch 1 taken 262947867 times.
262949850 else if(cmb.genflags & cflag3)
7062 {
7063 1983 cmb_z = cmb.z_height;
7064
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 cmb_z_step = zc_max(0_zf,cmb.z_step_height);
7065 1983 }
7066 262947867 else return false;
7067
7068
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
5953 if (standing_z_state == STANDING_Z_MAX) // 'infinity'
7069 return true;
7070
2/2
✓ Branch 0 taken 1149 times.
✓ Branch 1 taken 4804 times.
5953 if (!cmb_z) return false; // infinite height
7071
7072 4804 return (cmb_z - cmb_z_step) <= standing_z_state;
7073 262953820 }
7074 62151529 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
7075 {
7076 62151529 return _walkflag(zx,zy,cnt,0_zf);
7077 }
7078
7079 142613556 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& standing_z_state, bool is_temp_screens)
7080 {
7081 142613556 int x = zx.getRound(), y = zy.getRound();
7082 142613556 int pos = COMBOPOS(x % 256, y % 176);
7083 142613556 const newcombo& c = combobuf[s0->data[pos]];
7084 142613556 const newcombo& c1 = combobuf[s1->data[pos]];
7085 142613556 const newcombo& c2 = combobuf[s2->data[pos]];
7086
4/4
✓ Branch 0 taken 140521930 times.
✓ Branch 1 taken 2091626 times.
✓ Branch 2 taken 140512470 times.
✓ Branch 3 taken 9460 times.
285457102 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7087
4/4
✓ Branch 0 taken 114995 times.
✓ Branch 1 taken 140627465 times.
✓ Branch 2 taken 2211836 times.
✓ Branch 3 taken 4245 times.
142613556 (iswater_type(c2.type))) && DRIEDLAKE);
7088 142843546 int32_t b=1;
7089
2/2
✓ Branch 0 taken 70425412 times.
✓ Branch 1 taken 72418134 times.
142843546 if(x&8) b<<=2;
7090
2/2
✓ Branch 0 taken 66770084 times.
✓ Branch 1 taken 76073462 times.
142843546 if(y&8) b<<=1;
7091
7092 142843546 int32_t cwalkflag = c.walk;
7093
4/4
✓ Branch 0 taken 142728542 times.
✓ Branch 1 taken 115004 times.
✓ Branch 2 taken 142728378 times.
✓ Branch 3 taken 164 times.
142843546 if(is_temp_screens && standing_on_z(c,standing_z_state)) cwalkflag &= (c.walk>>4)^0xF;
7094
8/10
✓ Branch 0 taken 57502 times.
✓ Branch 1 taken 142785880 times.
✓ Branch 2 taken 2206612 times.
✓ Branch 3 taken 2149110 times.
✓ Branch 4 taken 2206612 times.
✓ Branch 5 taken 142728378 times.
✓ Branch 6 taken 2206612 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2206612 times.
✗ Branch 9 not taken.
142843382 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7095
2/2
✓ Branch 0 taken 63212165 times.
✓ Branch 1 taken 79516377 times.
142728542 if (s1 != s0)
7096 {
7097
3/4
✓ Branch 0 taken 79516377 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 79515759 times.
✓ Branch 3 taken 618 times.
79516377 if(is_temp_screens && standing_on_z(c1,standing_z_state)) cwalkflag &= (c1.walk>>4)^0xF;
7098
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 79504030 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
79515759 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
7099
2/2
✓ Branch 0 taken 71255 times.
✓ Branch 1 taken 79444504 times.
79515759 else if (c1.type == cBRIDGE)
7100 {
7101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 71255 times.
71255 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7102 {
7103 71255 int efflag = (c1.walk & 0xF0)>>4;
7104 71255 int newsolid = (c1.walk & 0xF);
7105 71255 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7106 71255 }
7107 else cwalkflag &= c1.walk;
7108 71255 }
7109
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 79432775 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
79444504 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
7110 79444504 else cwalkflag |= c1.walk;
7111 79516377 }
7112
2/2
✓ Branch 0 taken 102019641 times.
✓ Branch 1 taken 40708901 times.
142728542 if (s2 != s0)
7113 {
7114
2/4
✓ Branch 0 taken 40708901 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40708901 times.
✗ Branch 3 not taken.
40708901 if(is_temp_screens && standing_on_z(c2,standing_z_state)) cwalkflag &= (c2.walk>>4)^0xF;
7115
7/10
✓ Branch 0 taken 5889 times.
✓ Branch 1 taken 40703012 times.
✓ Branch 2 taken 5889 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3735 times.
✓ Branch 5 taken 2154 times.
✓ Branch 6 taken 3735 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 3735 times.
40708901 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
7116
2/2
✓ Branch 0 taken 16725 times.
✓ Branch 1 taken 40688441 times.
40705166 else if (c2.type == cBRIDGE)
7117 {
7118
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16725 times.
16725 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
7119 {
7120 16725 int efflag = (c2.walk & 0xF0)>>4;
7121 16725 int newsolid = (c2.walk & 0xF);
7122 16725 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
7123 16725 }
7124 else cwalkflag &= c2.walk;
7125 16725 }
7126
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 40686287 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
40688441 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
7127 40688441 else cwalkflag |= c2.walk;
7128 40708901 }
7129
7130
4/4
✓ Branch 0 taken 30808218 times.
✓ Branch 1 taken 111920324 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 30807270 times.
142728542 if((cwalkflag&b) && !dried)
7131 30807270 return true;
7132
7133
3/4
✓ Branch 0 taken 111921272 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 111852082 times.
✓ Branch 3 taken 69190 times.
111921272 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
7134
7135 111852082 return false;
7136 142728542 }
7137
7138 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
7139 142728542 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& standing_z_state)
7140 {
7141 142728542 int x = zx.getRound(), y = zy.getRound();
7142 142728542 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
7143 142728542 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7144 142728542 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7145
2/2
✓ Branch 0 taken 63212165 times.
✓ Branch 1 taken 79516377 times.
142728542 if (!s1->valid) s1 = s0;
7146
2/2
✓ Branch 0 taken 102019641 times.
✓ Branch 1 taken 40708901 times.
142728542 if (!s2->valid) s2 = s0;
7147 142728542 return _walkflag_new(s0, s1, s2, zx, zy, standing_z_state, true);
7148 }
7149
7150 138200665 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& standing_z_state)
7151 {
7152 138200665 int max_x = world_w;
7153 138200665 int max_y = world_h;
7154
2/2
✓ Branch 0 taken 78157928 times.
✓ Branch 1 taken 60042737 times.
138200665 if (!get_qr(qr_LTTPWALK))
7155 {
7156 60042737 max_x -= 7;
7157 60042737 max_y -= 7;
7158 60042737 }
7159
4/4
✓ Branch 0 taken 137928297 times.
✓ Branch 1 taken 272368 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 137845029 times.
138200665 if (x < 0 || y < 0) return false;
7160
2/2
✓ Branch 0 taken 323548 times.
✓ Branch 1 taken 137521481 times.
137845029 if (x >= max_x) return false;
7161
3/4
✓ Branch 0 taken 571808 times.
✓ Branch 1 taken 136949673 times.
✓ Branch 2 taken 571808 times.
✗ Branch 3 not taken.
137521481 if (x >= max_x - 8 && cnt == 2) return false;
7162
2/2
✓ Branch 0 taken 136967218 times.
✓ Branch 1 taken 554263 times.
137521481 if (y >= max_y) return false;
7163
7164
4/4
✓ Branch 0 taken 30758225 times.
✓ Branch 1 taken 106208993 times.
✓ Branch 2 taken 100447669 times.
✓ Branch 3 taken 5761324 times.
136967218 return _walkflag_new(x, y, standing_z_state) || (cnt != 1 && _walkflag_new(x + 8, y, standing_z_state));
7165 138200665 }
7166
7167 105128830 static bool effectflag(int32_t x, int32_t y, int32_t layer)
7168 {
7169 105128830 mapscr* s0 = get_scr_for_world_xy(x, y);
7170 105128830 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
7171 105128830 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
7172
2/2
✓ Branch 0 taken 57655235 times.
✓ Branch 1 taken 47473595 times.
105128830 if (!s1->valid) s1 = s0;
7173
2/2
✓ Branch 0 taken 24622036 times.
✓ Branch 1 taken 80506794 times.
105128830 if (!s2->valid) s2 = s0;
7174
7175 105128830 int pos = COMBOPOS(x % 256, y % 176);
7176 105128830 const newcombo& c = combobuf[s0->data[pos]];
7177 105128830 const newcombo& c1 = combobuf[s1->data[pos]];
7178 105128830 const newcombo& c2 = combobuf[s2->data[pos]];
7179
4/4
✓ Branch 0 taken 104133126 times.
✓ Branch 1 taken 995704 times.
✓ Branch 2 taken 104131846 times.
✓ Branch 3 taken 1280 times.
210257660 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
7180
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 104131846 times.
✓ Branch 2 taken 995300 times.
✓ Branch 3 taken 1684 times.
105128830 (iswater_type(c2.type))) && DRIEDLAKE);
7181 105128830 int32_t b=1;
7182
2/2
✓ Branch 0 taken 53202348 times.
✓ Branch 1 taken 51926482 times.
105128830 if(x&8) b<<=2;
7183
2/2
✓ Branch 0 taken 44691957 times.
✓ Branch 1 taken 60436873 times.
105128830 if(y&8) b<<=1;
7184
7185 105128830 int32_t cwalkflag = (c.walk>>4);
7186
2/2
✓ Branch 0 taken 80367289 times.
✓ Branch 1 taken 24761541 times.
105128830 if (layer == 0) cwalkflag = (c1.walk>>4);
7187
2/2
✓ Branch 0 taken 80368883 times.
✓ Branch 1 taken 24759947 times.
105128830 if (layer == 1) cwalkflag = (c2.walk>>4);
7188 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
7189
4/4
✓ Branch 0 taken 57655235 times.
✓ Branch 1 taken 47473595 times.
✓ Branch 2 taken 24571560 times.
✓ Branch 3 taken 33083675 times.
105128830 if (s1 != s0 && layer < 0)
7190 {
7191
2/2
✓ Branch 0 taken 24555346 times.
✓ Branch 1 taken 16214 times.
24571560 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
7192 24571560 }
7193
4/4
✓ Branch 0 taken 24622036 times.
✓ Branch 1 taken 80506794 times.
✓ Branch 2 taken 17773115 times.
✓ Branch 3 taken 6848921 times.
105128830 if (s2 != s0 && layer < 1)
7194 {
7195
2/2
✓ Branch 0 taken 17761231 times.
✓ Branch 1 taken 11884 times.
17773115 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
7196 17773115 }
7197
7198
2/2
✓ Branch 0 taken 104950826 times.
✓ Branch 1 taken 178004 times.
105128830 return (cwalkflag&b) ? !dried : false;
7199 }
7200
7201 105502154 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
7202 {
7203 DCHECK(cnt == 0 || cnt == 1);
7204 105502154 int max_x = world_w;
7205 105502154 int max_y = world_h;
7206
3/4
✓ Branch 0 taken 45833723 times.
✓ Branch 1 taken 59668431 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45833723 times.
105502154 if (!get_qr(qr_LTTPWALK) && !notLink)
7207 {
7208 45833723 max_x -= 7;
7209 45833723 max_y -= 7;
7210 45833723 }
7211
4/4
✓ Branch 0 taken 105501402 times.
✓ Branch 1 taken 752 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 105501198 times.
105502154 if (x < 0 || y < 0) return false;
7212
2/2
✓ Branch 0 taken 816 times.
✓ Branch 1 taken 105500382 times.
105501198 if (x >= max_x) return false;
7213
3/4
✓ Branch 0 taken 526426 times.
✓ Branch 1 taken 104973956 times.
✓ Branch 2 taken 526426 times.
✗ Branch 3 not taken.
105500382 if (x >= max_x - 8 && cnt == 2) return false;
7214
2/2
✓ Branch 0 taken 371552 times.
✓ Branch 1 taken 105128830 times.
105500382 if (y >= max_y) return false;
7215
7216
3/4
✓ Branch 0 taken 104950036 times.
✓ Branch 1 taken 178794 times.
✓ Branch 2 taken 178794 times.
✗ Branch 3 not taken.
105128830 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
7217 105502154 }
7218
7219 // used by mapdata->isSolid(x,y) in ZScript
7220 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7221 {
7222 int x = zx.getRound(), y = zy.getRound();
7223 {
7224 int max_x = 256;
7225 int max_y = 176;
7226 if (!get_qr(qr_LTTPWALK))
7227 {
7228 max_x -= 7;
7229 max_y -= 7;
7230 }
7231 if (x < 0 || y < 0) return false;
7232 if (x >= max_x) return false;
7233 if (x >= max_x - 8 && cnt == 2) return false;
7234 if (y >= max_y) return false;
7235 }
7236
7237 const mapscr *s1, *s2;
7238 s1 = s2 = m;
7239
7240 if ( m->layermap[0] > 0 && m->layermap[0] <= map_count )
7241 {
7242 const mapscr* s = get_canonical_scr(m->layermap[0] - 1, m->layerscreen[0]);
7243 if (s->is_valid())
7244 s1 = s;
7245 }
7246
7247 if ( m->layermap[1] > 0 && m->layermap[1] <= map_count )
7248 {
7249 const mapscr* s = get_canonical_scr(m->layermap[1] - 1, m->layerscreen[1]);
7250 if (s->is_valid())
7251 s2 = s;
7252 }
7253
7254 zfix unused;
7255 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
7256 }
7257
7258 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
7259 {
7260 DCHECK_LAYER_NEG1_INDEX(layer);
7261 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7262 if (!m->is_valid()) return false;
7263 return _walkflag_layer(x, y, cnt, m);
7264 }
7265
7266 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
7267 {
7268 int x = zx.getRound(), y = zy.getRound();
7269
7270 if (!get_qr(qr_LTTPWALK))
7271 {
7272 max_x -= 7;
7273 max_y -= 7;
7274 }
7275 if (x < 0 || y < 0) return false;
7276 if (x >= max_x) return false;
7277 if (x >= max_x - 8 && cnt == 2) return false;
7278 if (y >= max_y) return false;
7279
7280 if(!m) return true;
7281
7282 int pos = COMBOPOS(x%256, y%176);
7283 const newcombo* c = &combobuf[m->data[pos]];
7284 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7285 int32_t b=1;
7286
7287 if(x&8) b<<=2;
7288
7289 if(y&8) b<<=1;
7290
7291 if((c->walk&b) && !dried)
7292 return true;
7293
7294 if(cnt==1) return false;
7295
7296 ++pos;
7297
7298 if(!(x&8))
7299 b<<=2;
7300 else
7301 {
7302 c = &combobuf[m->data[pos]];
7303 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7304 b=1;
7305
7306 if(y&8) b<<=1;
7307 }
7308
7309 return (c->walk&b) ? !dried : false;
7310 }
7311
7312 //Only check the given mapscr*, not its layer 1&2
7313 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7314 {
7315 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7316 }
7317
7318 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7319 {
7320 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7321 }
7322
7323 447898 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7324 {
7325 DCHECK_LAYER_NEG1_INDEX(layer);
7326 447898 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7327
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 446136 times.
447898 if (!m->is_valid()) return false;
7328 446136 return _effectflag_layer(x, y, cnt, m, notLink);
7329 447898 }
7330
7331 519213 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7332 {
7333 519213 int max_x = world_w;
7334 519213 int max_y = world_h;
7335
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 469211 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
519213 if (!get_qr(qr_LTTPWALK) && !notLink)
7336 {
7337 max_x -= 7;
7338 max_y -= 7;
7339 }
7340
2/4
✓ Branch 0 taken 519213 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 519213 times.
519213 if (x < 0 || y < 0) return false;
7341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 519213 times.
519213 if (x >= max_x) return false;
7342
3/4
✓ Branch 0 taken 1342 times.
✓ Branch 1 taken 517871 times.
✓ Branch 2 taken 1342 times.
✗ Branch 3 not taken.
519213 if (x >= max_x - 8 && cnt == 2) return false;
7343
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 519213 times.
519213 if (y >= max_y) return false;
7344
7345
1/2
✓ Branch 0 taken 519213 times.
✗ Branch 1 not taken.
519213 if (!m) return true;
7346
7347 519213 int pos = COMBOPOS(x%256, y%176);
7348 519213 const newcombo* c = &combobuf[m->data[pos]];
7349
3/4
✓ Branch 0 taken 518813 times.
✓ Branch 1 taken 400 times.
✓ Branch 2 taken 400 times.
✗ Branch 3 not taken.
519613 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7350 519213 int32_t b=1;
7351
7352
2/2
✓ Branch 0 taken 276528 times.
✓ Branch 1 taken 242685 times.
519213 if(x&8) b<<=2;
7353
7354
2/2
✓ Branch 0 taken 220331 times.
✓ Branch 1 taken 298882 times.
519213 if(y&8) b<<=1;
7355
7356
3/4
✓ Branch 0 taken 450224 times.
✓ Branch 1 taken 68989 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 450224 times.
519213 if(((c->walk>>4)&b) && !dried)
7357 450224 return true;
7358
7359
1/2
✓ Branch 0 taken 68989 times.
✗ Branch 1 not taken.
68989 if(cnt==1) return false;
7360
7361 ++pos;
7362
7363 if(!(x&8))
7364 b<<=2;
7365 else
7366 {
7367 c = &combobuf[m->data[pos]];
7368 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7369 b=1;
7370
7371 if(y&8) b<<=1;
7372 }
7373
7374 return ((c->walk>>4)&b) ? !dried : false;
7375 519213 }
7376
7377 860420 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7378 {
7379 860420 int max_x = world_w;
7380 860420 int max_y = world_h;
7381
2/2
✓ Branch 0 taken 165182 times.
✓ Branch 1 taken 695238 times.
860420 if (!get_qr(qr_LTTPWALK))
7382 {
7383 695238 max_x -= 7;
7384 695238 max_y -= 7;
7385 695238 }
7386
2/4
✓ Branch 0 taken 860420 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 860420 times.
860420 if (x < 0 || y < 0) return false;
7387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if (x >= max_x) return false;
7388
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
860420 if (x >= max_x - 8 && cnt == 2) return false;
7389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if (y >= max_y) return false;
7390
7391
3/4
✓ Branch 0 taken 17860 times.
✓ Branch 1 taken 842560 times.
✓ Branch 2 taken 842560 times.
✗ Branch 3 not taken.
860420 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7392 860420 }
7393
7394 860420 bool water_walkflag(int32_t x, int32_t y)
7395 {
7396 860420 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7397 860420 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7398 860420 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7399
7400 860420 int32_t b=1;
7401
2/2
✓ Branch 0 taken 439102 times.
✓ Branch 1 taken 421318 times.
860420 if(x&8) b<<=2;
7402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 860420 times.
860420 if(y&8) b<<=1;
7403
7404
2/2
✓ Branch 0 taken 74192 times.
✓ Branch 1 taken 786228 times.
860420 if(get_qr(qr_NO_SOLID_SWIM))
7405 {
7406
2/2
✓ Branch 0 taken 474 times.
✓ Branch 1 taken 73718 times.
74192 if(c.walk&b)
7407 474 return true;
7408
7409
2/2
✓ Branch 0 taken 914 times.
✓ Branch 1 taken 72804 times.
73718 if(c1.walk&b)
7410 914 return true;
7411
7412
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 72733 times.
72804 if(c2.walk&b)
7413 71 return true;
7414 72733 }
7415 else
7416 {
7417
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7418 16371 return true;
7419
7420
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7421 17 return true;
7422
7423
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7424 13 return true;
7425 }
7426
7427 842560 return false;
7428 860420 }
7429
7430 589885 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7431 {
7432
2/2
✓ Branch 0 taken 100391 times.
✓ Branch 1 taken 489494 times.
589885 if(dlevel)
7433
8/8
✓ Branch 0 taken 488049 times.
✓ Branch 1 taken 1445 times.
✓ Branch 2 taken 484722 times.
✓ Branch 3 taken 3327 times.
✓ Branch 4 taken 483005 times.
✓ Branch 5 taken 1717 times.
✓ Branch 6 taken 4386 times.
✓ Branch 7 taken 478619 times.
489494 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7434 10875 return true;
7435
7436
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 579008 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
579010 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7437 return true;
7438
7439
8/8
✓ Branch 0 taken 578724 times.
✓ Branch 1 taken 286 times.
✓ Branch 2 taken 578481 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 578270 times.
✓ Branch 5 taken 211 times.
✓ Branch 6 taken 396 times.
✓ Branch 7 taken 577874 times.
579010 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7440 1136 return true;
7441
7442 // for(int32_t i=0; i<4; i++)
7443
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 577033 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
577874 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7444 36 return true;
7445
7446
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 577837 times.
577838 if (collide_object(x, y,cnt*8, 1))
7447 1 return true;
7448
7449 577837 return _walkflag(x,y,cnt);
7450 589885 }
7451
7452 12220 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7453 {
7454 // 16 pixel buffer to account for slopes that are on bordering screens.
7455
4/8
✓ Branch 0 taken 12220 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12220 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12220 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12220 times.
12220 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7456 return true;
7457
7458 // for(int32_t i=0; i<4; i++)
7459
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12220 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12220 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7460 return true;
7461
7462
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12220 times.
12220 if (collide_object(x, y,cnt*8, 1, ign))
7463 return true;
7464
7465 12220 return _walkflag(x,y,cnt);
7466 12220 }
7467
7468 39586 void map_bkgsfx(bool on)
7469 {
7470
2/2
✓ Branch 0 taken 39565 times.
✓ Branch 1 taken 21 times.
39586 if(on)
7471 {
7472 39565 cont_sfx(hero_scr->oceansfx);
7473
7474
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 39196 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
39565 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&(1 << li_boss_killed)))
7475 315 cont_sfx(hero_scr->bosssfx);
7476 39565 }
7477 else
7478 {
7479 21 adjust_sfx(hero_scr->oceansfx,128,false);
7480 21 adjust_sfx(hero_scr->bosssfx,128,false);
7481
7482
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7483 {
7484
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7485 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7486 114 }
7487 }
7488 39586 }
7489
7490 261 void toggle_switches(dword flags, bool entry)
7491 {
7492
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 261 times.
261 if(!flags) return; //No flags to toggle
7493
7494 522 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7495 261 toggle_switches(flags, entry, create_screen_handles(scr));
7496 261 });
7497 261 }
7498 55202 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7499 {
7500
2/2
✓ Branch 0 taken 931 times.
✓ Branch 1 taken 54271 times.
55202 if(!flags) return; //No flags to toggle
7501
7502 931 mapscr* m = screen_handles[0].base_scr;
7503 931 int screen = m->screen;
7504 931 bool is_active_screen = is_in_current_region(m);
7505
7506 525235 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7507 524304 byte togglegrid[176] = {0};
7508 524304 mapscr* scr = rpos_handle.scr;
7509 524304 int lyr = rpos_handle.layer;
7510 524304 int pos = rpos_handle.pos;
7511 524304 newcombo const& cmb = combobuf[scr->data[pos]];
7512
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 484880 times.
524304 if(is_active_screen)
7513
1/2
✓ Branch 0 taken 484880 times.
✗ Branch 1 not taken.
641011 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7514
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 156131 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
156131 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7515 }, ctrigSWITCHSTATE);
7516
3/4
✓ Branch 0 taken 523592 times.
✓ Branch 1 taken 712 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2809 times.
524304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7517
2/2
✓ Branch 0 taken 2809 times.
✓ Branch 1 taken 521495 times.
524304 && !(cmb.usrflags & cflag11)) //global state
7518 {
7519
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2363 times.
2809 if(flags&(1<<cmb.attribytes[0]))
7520 {
7521 2363 set<int32_t> oldData;
7522 //Increment the combo/cset by the attributes
7523 2363 int32_t cmbofs = (cmb.attributes[0]/10000L);
7524 2363 int32_t csofs = (cmb.attributes[1]/10000L);
7525
1/2
✓ Branch 0 taken 2363 times.
✗ Branch 1 not taken.
2363 oldData.insert(scr->data[pos]);
7526
1/2
✓ Branch 0 taken 2363 times.
✗ Branch 1 not taken.
2363 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7527 2363 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7528
4/4
✓ Branch 0 taken 1444 times.
✓ Branch 1 taken 919 times.
✓ Branch 2 taken 1206 times.
✓ Branch 3 taken 238 times.
2363 if(entry && (cmb.usrflags&cflag8))
7529 {
7530 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7531
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7532 {
7533 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7534 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7535 if(oldData.find(cid) != oldData.end())
7536 break;
7537
7538 scr->data[pos] = cid;
7539 if(!(tmp->animflags & AF_CYCLENOCSET))
7540 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7541 oldData.insert(cid);
7542 tmp = &combobuf[cid];
7543 }
7544 238 }
7545 2363 int32_t cmbid = scr->data[pos];
7546
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2322 times.
2363 if(combobuf[cmbid].animflags & AF_CYCLE)
7547 {
7548 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7549 41 combobuf[cmbid].cur_frame=0;
7550 41 combobuf[cmbid].aclk = 0;
7551
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7552 41 }
7553 2363 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7554
2/2
✓ Branch 0 taken 560 times.
✓ Branch 1 taken 1803 times.
2363 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7555
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2147 times.
2147 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7556 {
7557
2/2
✓ Branch 0 taken 1671 times.
✓ Branch 1 taken 476 times.
2147 if(lyr==lyr2) return;
7558
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 344 times.
476 if(!(cmb.usrflags&(1<<lyr2))) return;
7559
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(togglegrid[pos]&(1<<lyr2)) return;
7560
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
344 mapscr* scr_2 = (lyr2 ? get_scr_layer(screen, lyr2) : m);
7561
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7562 return;
7563 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7564
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7565 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7566 return; //This is a switch/block that will be hit later in the loop!
7567 344 set<int32_t> oldData2;
7568 //Increment the combo/cset by the original cmb's attributes
7569
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7570
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7571 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7572
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7573 {
7574 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7575 while(tmp->can_cycle())
7576 {
7577 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7578 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7579 if(oldData2.find(cid) != oldData2.end())
7580 break;
7581
7582 scr_2->data[pos] = cid;
7583 if(!(tmp->animflags & AF_CYCLENOCSET))
7584 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7585 oldData2.insert(cid);
7586 tmp = &combobuf[cid];
7587 }
7588 }
7589 344 int32_t cmbid2 = scr_2->data[pos];
7590
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7591 {
7592 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7593 combobuf[cmbid2].cur_frame=0;
7594 combobuf[cmbid2].aclk = 0;
7595 combo_caches::drawing.refresh(cmbid2);
7596 }
7597 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7598 344 }
7599
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2363 times.
✗ Branch 2 not taken.
2363 }
7600 446 }
7601 524304 });
7602
7603
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 412 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
931 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7604 {
7605 newcombo const& cmb = combobuf[mblock2.bcombo];
7606 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7607 {
7608 if(flags&(1<<cmb.attribytes[0]))
7609 {
7610 //Increment the combo/cset by the attributes
7611 int32_t cmbofs = (cmb.attributes[0]/10000L);
7612 int32_t csofs = (cmb.attributes[1]/10000L);
7613 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7614 mblock2.cs = (mblock2.cs + csofs) & 15;
7615 int32_t cmbid = mblock2.bcombo;
7616 if(combobuf[cmbid].animflags & AF_CYCLE)
7617 {
7618 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7619 combobuf[cmbid].cur_frame=0;
7620 combobuf[cmbid].aclk = 0;
7621 combo_caches::drawing.refresh(cmbid);
7622 }
7623 }
7624 }
7625 }
7626
7627
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 707 times.
931 if (is_active_screen)
7628 {
7629 707 int screen_index_offset = get_region_screen_offset(m->screen);
7630 707 word c = m->numFFC();
7631
2/2
✓ Branch 0 taken 565 times.
✓ Branch 1 taken 707 times.
1272 for (int q = 0; q < c; ++q)
7632 {
7633 565 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7634
1/2
✓ Branch 0 taken 565 times.
✗ Branch 1 not taken.
596 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7635
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
31 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7636 }, ctrigSWITCHSTATE);
7637 565 }
7638 707 }
7639 55202 }
7640
7641 1 void toggle_gswitches(int32_t state, bool entry)
7642 {
7643 2 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7644 1 toggle_gswitches(state, entry, create_screen_handles(scr));
7645 1 });
7646 1 }
7647 1 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7648 {
7649 1 bool states[256] = {false};
7650 1 states[state] = true;
7651 1 toggle_gswitches(states, entry, screen_handles);
7652 1 }
7653 15792082 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7654 {
7655
1/2
✓ Branch 0 taken 15792082 times.
✗ Branch 1 not taken.
15792082 if(!states) return;
7656
7657 15792082 auto& combo_cache = combo_caches::gswitch;
7658 15792082 mapscr* base_scr = screen_handles[0].base_scr;
7659 15792082 int screen = base_scr->screen;
7660 15792082 bool is_active_screen = is_in_current_region(base_scr);
7661 15792082 byte togglegrid[176] = {0};
7662
2/2
✓ Branch 0 taken 15792082 times.
✓ Branch 1 taken 110544574 times.
126336656 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7663 {
7664 110544574 mapscr* scr = screen_handles[lyr].scr;
7665
2/2
✓ Branch 0 taken 35895108 times.
✓ Branch 1 taken 74649466 times.
110544574 if (!scr)
7666 74649466 continue;
7667
7668
2/2
✓ Branch 0 taken 35895108 times.
✓ Branch 1 taken 6317539008 times.
6353434116 for(int32_t pos = 0; pos < 176; ++pos)
7669 {
7670 6317539008 int cid = scr->data[pos];
7671 6317539008 auto& mini_cmb = combo_cache.minis[cid];
7672
7673
2/2
✓ Branch 0 taken 2910336 times.
✓ Branch 1 taken 6314628672 times.
6317539008 if (is_active_screen)
7674 {
7675
2/2
✓ Branch 0 taken 6314626790 times.
✓ Branch 1 taken 1882 times.
6314628672 if (mini_cmb.trigger_global_state)
7676 {
7677 1882 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7678
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
3764 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7679
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1882 times.
1882 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7680 }, ctrigSWITCHSTATE);
7681 1882 }
7682 6314628672 }
7683
7684
2/2
✓ Branch 0 taken 55356 times.
✓ Branch 1 taken 6317483652 times.
6317539008 if (!mini_cmb.has_global_state)
7685 6317483652 continue;
7686
7687 55356 newcombo const& cmb = combobuf[cid];
7688
2/4
✓ Branch 0 taken 55356 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 55356 times.
55356 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7689 {
7690 if(states[cmb.attribytes[0]])
7691 {
7692 set<int32_t> oldData;
7693 //Increment the combo/cset by the attributes
7694 int32_t cmbofs = (cmb.attributes[0]/10000L);
7695 int32_t csofs = (cmb.attributes[1]/10000L);
7696 oldData.insert(scr->data[pos]);
7697 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7698 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7699 if(entry && (cmb.usrflags&cflag8))
7700 {
7701 newcombo const* tmp = &combobuf[scr->data[pos]];
7702 while(tmp->can_cycle())
7703 {
7704 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7705 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7706 if(oldData.find(cid) != oldData.end())
7707 break;
7708 scr->data[pos] = cid;
7709 if(!(tmp->animflags & AF_CYCLENOCSET))
7710 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7711 oldData.insert(cid);
7712 tmp = &combobuf[cid];
7713 }
7714 }
7715 int32_t cmbid = scr->data[pos];
7716 if(combobuf[cmbid].animflags & AF_CYCLE)
7717 {
7718 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7719 combobuf[cmbid].cur_frame=0;
7720 combobuf[cmbid].aclk = 0;
7721 combo_caches::drawing.refresh(cmbid);
7722 }
7723 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7724 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7725 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7726 {
7727 if(lyr==lyr2) continue;
7728 if(!(cmb.usrflags&(1<<lyr2))) continue;
7729 if(togglegrid[pos]&(1<<lyr2)) continue;
7730 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7731 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7732 continue;
7733 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7734 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7735 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7736 continue; //This is a switch/block that will be hit later in the loop!
7737 set<int32_t> oldData2;
7738 //Increment the combo/cset by the original cmb's attributes
7739 oldData2.insert(scr_2->data[pos]);
7740 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7741 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7742 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7743 {
7744 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7745 while(tmp->can_cycle())
7746 {
7747 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7748 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7749 if(oldData2.find(cid) != oldData2.end())
7750 break;
7751 scr_2->data[pos] = cid;
7752 if(!(tmp->animflags & AF_CYCLENOCSET))
7753 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7754 oldData2.insert(cid);
7755 tmp = &combobuf[cid];
7756 }
7757 }
7758 int32_t cmbid2 = scr_2->data[pos];
7759 if(combobuf[cmbid2].animflags & AF_CYCLE)
7760 {
7761 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7762 combobuf[cmbid2].cur_frame=0;
7763 combobuf[cmbid2].aclk = 0;
7764 combo_caches::drawing.refresh(cmbid2);
7765 }
7766 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7767 }
7768 }
7769 }
7770 55356 }
7771 35895108 }
7772
7773
4/4
✓ Branch 0 taken 549907 times.
✓ Branch 1 taken 15242175 times.
✓ Branch 2 taken 545163 times.
✓ Branch 3 taken 4744 times.
15792082 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7774 {
7775 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7776
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7777 {
7778 if(states[cmb.attribytes[0]])
7779 {
7780 //Increment the combo/cset by the attributes
7781 int32_t cmbofs = (cmb.attributes[0]/10000L);
7782 int32_t csofs = (cmb.attributes[1]/10000L);
7783 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7784 mblock2.cs = (mblock2.cs + csofs) & 15;
7785 int32_t cmbid = mblock2.bcombo;
7786 if(combobuf[cmbid].animflags & AF_CYCLE)
7787 {
7788 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7789 combobuf[cmbid].cur_frame=0;
7790 combobuf[cmbid].aclk = 0;
7791 combo_caches::drawing.refresh(cmbid);
7792 }
7793 }
7794 }
7795 4744 }
7796
7797
2/2
✓ Branch 0 taken 16159 times.
✓ Branch 1 taken 15775923 times.
15792082 if(is_active_screen)
7798 {
7799 15775923 int screen_index_offset = get_region_screen_offset(screen);
7800 15775923 word c = base_scr->numFFC();
7801
2/2
✓ Branch 0 taken 455562886 times.
✓ Branch 1 taken 15775923 times.
471338809 for (int q = 0; q < c; ++q)
7802 {
7803 455562886 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7804
1/2
✓ Branch 0 taken 455562886 times.
✗ Branch 1 not taken.
455796224 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7805
1/2
✓ Branch 0 taken 233338 times.
✗ Branch 1 not taken.
233338 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7806 }, ctrigSWITCHSTATE);
7807 455562886 }
7808 15775923 }
7809 15792082 }
7810 54941 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7811 {
7812 bool states[256];
7813
2/2
✓ Branch 0 taken 14064896 times.
✓ Branch 1 taken 54941 times.
14119837 for(auto q = 0; q < 256; ++q)
7814 {
7815 14064896 states[q] = game->gswitch_timers[q] != 0;
7816 14064896 }
7817 54941 toggle_gswitches(states, true, screen_handles);
7818 54941 }
7819 15347772 void run_gswitch_timers()
7820 {
7821 15347772 bool states[256] = {false};
7822 15347772 auto& m = game->gswitch_timers.mut_inner();
7823
2/2
✓ Branch 0 taken 3924987392 times.
✓ Branch 1 taken 15347772 times.
3940335164 for(auto it = m.begin(); it != m.end();)
7824 {
7825
2/2
✓ Branch 0 taken 3924986792 times.
✓ Branch 1 taken 600 times.
3924987392 if(it->second > 0)
7826
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 1 times.
600 if(!--it->second)
7827 {
7828 1 states[it->first] = true;
7829 1 it = m.erase(it);
7830 1 continue;
7831 }
7832 3924987391 ++it;
7833 }
7834 31084912 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7835 15737140 toggle_gswitches(states, false, create_screen_handles(scr));
7836 15737140 });
7837 15347772 }
7838 1147 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7839 {
7840
2/2
✓ Branch 0 taken 293632 times.
✓ Branch 1 taken 1147 times.
294779 for(auto q = 0; q < 256; ++q)
7841 {
7842
1/2
✓ Branch 0 taken 293632 times.
✗ Branch 1 not taken.
293632 if(game->gswitch_timers[q] > 0)
7843 game->gswitch_timers[q] = 0;
7844 293632 }
7845 1147 }
7846
7847 /**** View Map ****/
7848
7849 int32_t mapres = 0;
7850 int32_t view_map_show_mode = 3;
7851
7852 129280 bool displayOnMap(int32_t x, int32_t y)
7853 {
7854 129280 int32_t s = (y<<4) + x;
7855 129280 int mi = mapind(cur_map, s);
7856
2/2
✓ Branch 0 taken 70863 times.
✓ Branch 1 taken 58417 times.
129280 if (!(game->maps[mi]&mVISITED))
7857 70863 return false;
7858
7859 // Don't display if not part of DMap
7860
4/4
✓ Branch 0 taken 15807 times.
✓ Branch 1 taken 42610 times.
✓ Branch 2 taken 4750 times.
✓ Branch 3 taken 4311 times.
67478 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7861
1/2
✓ Branch 0 taken 15807 times.
✗ Branch 1 not taken.
15807 (DMaps[cur_dmap].type != dmOVERW) &&
7862
2/2
✓ Branch 0 taken 12631 times.
✓ Branch 1 taken 3176 times.
15807 !(x >= DMaps[cur_dmap].xoff &&
7863
2/2
✓ Branch 0 taken 9061 times.
✓ Branch 1 taken 3570 times.
12631 x < DMaps[cur_dmap].xoff+8 &&
7864 9061 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7865 11057 return false;
7866 else
7867 47360 return true;
7868 129280 }
7869
7870 1010 void ViewMap()
7871 {
7872 1010 ViewingMap = true;
7873
7874 1010 BITMAP* mappic = NULL;
7875 static double scales[17] =
7876 {
7877 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7878 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7879 };
7880
7881 // Cursor position for hero, in absolute map coordinates.
7882 1010 int32_t lx = ((cur_screen & 15) << 8) + HeroX() + 8;
7883 1010 int32_t ly = ((cur_screen >> 4) * 176) + HeroY() + 8;
7884
7885 int32_t px;
7886 int32_t py;
7887
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1010 times.
1010 if (is_in_scrolling_region())
7888 {
7889 // Center the player on the middle of the map view.
7890 px = (16*256/2 - lx) * 2;
7891 py = (8*176/2 - ly) * 2;
7892 }
7893 else
7894 {
7895 // Center the current screen on the middle of the map view.
7896 1010 px = ((8-(cur_screen&15)) << 9) - 256;
7897 1010 py = ((4-(cur_screen>>4)) * 352) - 176;
7898 }
7899
7900 1010 int32_t sc = 6;
7901
7902 1010 bool done=false, redraw=true;
7903
7904 1010 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7905
7906
1/2
✓ Branch 0 taken 1010 times.
✗ Branch 1 not taken.
1010 if(!mappic)
7907 {
7908 enter_sys_pal();
7909 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7910 exit_sys_pal();
7911 return;
7912 }
7913
7914 1010 clear_to_color(mappic, WHITE);
7915
7916 1010 auto prev_viewport = viewport;
7917 1010 viewport.x = 0;
7918 1010 viewport.y = 0;
7919
7920 // draw the map
7921 1010 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7922 1010 combotile_add_x = 256;
7923 1010 combotile_add_y = 0;
7924 1010 bool classic_draw = get_qr(qr_CLASSIC_DRAWING_ORDER);
7925
2/2
✓ Branch 0 taken 8080 times.
✓ Branch 1 taken 1010 times.
9090 for(int32_t y=0; y<8; y++)
7926 {
7927
2/2
✓ Branch 0 taken 8080 times.
✓ Branch 1 taken 129280 times.
137360 for(int32_t x=0; x<16; x++)
7928 {
7929
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 81920 times.
129280 if (!displayOnMap(x, y))
7930 81920 continue;
7931
7932 47360 int screen = map_scr_xy_to_index(x, y);
7933 47360 auto scrs = loadscr2(screen);
7934 47360 mapscr* scr = &scrs[0];
7935
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if (!scr->is_valid())
7936 continue;
7937
7938 screen_handles_t screen_handles;
7939
2/2
✓ Branch 0 taken 47360 times.
✓ Branch 1 taken 331520 times.
378880 for (int i = 0; i <= 6; i++)
7940
3/4
✓ Branch 0 taken 331520 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 114582 times.
✓ Branch 3 taken 216938 times.
331520 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7941
7942 47360 int xx = 0;
7943 47360 int yy = -playing_field_offset;
7944
7945
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 if (!classic_draw)
7946 for (int layer = -7; layer <= -4; ++layer)
7947 do_ffc_layer(screen_bmp, layer, screen_handles[0], xx, yy);
7948
7949
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 if(classic_draw)
7950 {
7951
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 47313 times.
47360 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7952
1/2
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
47 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7953
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7954 47360 }
7955
7956
2/2
✓ Branch 0 taken 213 times.
✓ Branch 1 taken 47147 times.
47360 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7957
1/2
✓ Branch 0 taken 213 times.
✗ Branch 1 not taken.
213 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7958
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7959
7960
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47360 times.
47360 if(!classic_draw)
7961 {
7962 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7963 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7964 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7965 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7966 }
7967
7968
2/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
✗ Branch 3 not taken.
47360 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7969
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7970
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7971
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7972
7973
2/2
✓ Branch 0 taken 47313 times.
✓ Branch 1 taken 47 times.
47360 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7974 {
7975
1/2
✓ Branch 0 taken 47313 times.
✗ Branch 1 not taken.
47313 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7976
1/2
✓ Branch 0 taken 47313 times.
✗ Branch 1 not taken.
47313 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7977 47313 }
7978
7979
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 putscrdoors(scr, screen_bmp, xx, yy);
7980
2/2
✓ Branch 0 taken 43358 times.
✓ Branch 1 taken 4002 times.
47360 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7981 {
7982
1/2
✓ Branch 0 taken 43358 times.
✗ Branch 1 not taken.
43358 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7983
2/2
✓ Branch 0 taken 3462 times.
✓ Branch 1 taken 39896 times.
43358 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7984 {
7985
1/2
✓ Branch 0 taken 3462 times.
✗ Branch 1 not taken.
3462 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7986
1/2
✓ Branch 0 taken 3462 times.
✗ Branch 1 not taken.
3462 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7987 3462 }
7988 43358 }
7989
7990
2/2
✓ Branch 0 taken 47147 times.
✓ Branch 1 taken 213 times.
47360 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7991 {
7992
1/2
✓ Branch 0 taken 47147 times.
✗ Branch 1 not taken.
47147 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7993
1/2
✓ Branch 0 taken 47147 times.
✗ Branch 1 not taken.
47147 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7994 47147 }
7995
7996
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7997
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7998
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7999
2/2
✓ Branch 0 taken 7464 times.
✓ Branch 1 taken 39896 times.
47360 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
8000 {
8001
1/2
✓ Branch 0 taken 7464 times.
✗ Branch 1 not taken.
7464 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
8002
1/2
✓ Branch 0 taken 7464 times.
✗ Branch 1 not taken.
7464 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
8003 7464 }
8004
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
8005
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
8006
3/4
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1680 times.
✓ Branch 3 taken 45680 times.
47360 if(replay_version_check(40))
8007
1/2
✓ Branch 0 taken 1680 times.
✗ Branch 1 not taken.
1680 do_ffc_layer(screen_bmp, -1000, screen_handles[0], xx, yy);
8008
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
8009
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
8010
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
8011
8012
1/2
✓ Branch 0 taken 47360 times.
✗ Branch 1 not taken.
47360 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
8013
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 47360 times.
47360 }
8014 8080 }
8015
8016 1010 viewport = prev_viewport;
8017 1010 combotile_add_x = 0;
8018 1010 combotile_add_y = 0;
8019
8020 1010 destroy_bitmap(screen_bmp);
8021 1010 clear_keybuf();
8022 1010 pause_all_sfx();
8023
8024 // view it
8025 1010 int32_t delay = 0;
8026
8027 1010 do
8028 {
8029
2/2
✓ Branch 0 taken 189085 times.
✓ Branch 1 taken 29891 times.
218976 if (replay_version_check(0, 11))
8030 29891 load_control_state();
8031
8032 218976 int32_t step = int32_t(16.0/scales[sc]);
8033 218976 step = (step>>1) + (step&1);
8034 218976 bool r = cRbtn();
8035
8036
1/2
✓ Branch 0 taken 218976 times.
✗ Branch 1 not taken.
218976 if(cLbtn())
8037 {
8038 step <<= 2;
8039 delay = 0;
8040 }
8041
8042
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 218976 times.
218976 if(r)
8043 {
8044 if(rUp())
8045 {
8046 py+=step;
8047 redraw=true;
8048 }
8049
8050 if(rDown())
8051 {
8052 py-=step;
8053 redraw=true;
8054 }
8055
8056 if(rLeft())
8057 {
8058 px+=step;
8059 redraw=true;
8060 }
8061
8062 if(rRight())
8063 {
8064 px-=step;
8065 redraw=true;
8066 }
8067 }
8068 else
8069 {
8070
2/2
✓ Branch 0 taken 203528 times.
✓ Branch 1 taken 15448 times.
218976 if(Up())
8071 {
8072 15448 py+=step;
8073 15448 redraw=true;
8074 15448 }
8075
8076
2/2
✓ Branch 0 taken 203410 times.
✓ Branch 1 taken 15566 times.
218976 if(Down())
8077 {
8078 15566 py-=step;
8079 15566 redraw=true;
8080 15566 }
8081
8082
2/2
✓ Branch 0 taken 191540 times.
✓ Branch 1 taken 27436 times.
218976 if(Left())
8083 {
8084 27436 px+=step;
8085 27436 redraw=true;
8086 27436 }
8087
8088
2/2
✓ Branch 0 taken 192194 times.
✓ Branch 1 taken 26782 times.
218976 if(Right())
8089 {
8090 26782 px-=step;
8091 26782 redraw=true;
8092 26782 }
8093 }
8094
8095
2/2
✓ Branch 0 taken 22044 times.
✓ Branch 1 taken 196932 times.
218976 if(delay)
8096 22044 --delay;
8097 else
8098 {
8099 196932 bool a = cAbtn();
8100 196932 bool b = cBbtn();
8101
8102
3/4
✓ Branch 0 taken 1786 times.
✓ Branch 1 taken 195146 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1786 times.
196932 if(a && !b)
8103 {
8104
1/2
✓ Branch 0 taken 1786 times.
✗ Branch 1 not taken.
1786 sc=zc_min(sc+1,16);
8105 1786 delay=8;
8106 1786 redraw=true;
8107 1786 }
8108
8109
3/4
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 195960 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 972 times.
196932 if(b && !a)
8110 {
8111
2/2
✓ Branch 0 taken 971 times.
✓ Branch 1 taken 1 times.
972 sc=zc_max(sc-1,0);
8112 972 delay=8;
8113 972 redraw=true;
8114 972 }
8115 }
8116
8117
2/2
✓ Branch 0 taken 218965 times.
✓ Branch 1 taken 11 times.
218976 if(rPbtn())
8118 11 --view_map_show_mode;
8119
8120 218976 px = vbound(px,-4096,4096);
8121 218976 py = vbound(py,-1408,1408);
8122
8123 218976 double scale = scales[sc];
8124
8125
2/2
✓ Branch 0 taken 75341 times.
✓ Branch 1 taken 143635 times.
218976 if(!redraw)
8126 {
8127 143635 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
8128 143635 }
8129 else
8130 {
8131 75341 clear_to_color(framebuf,BLACK);
8132 150682 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
8133 75341 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
8134 75341 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
8135
8136 75341 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
8137 75341 redraw=false;
8138 }
8139
8140 218976 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
8141 218976 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
8142
8143
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 211510 times.
218976 if(view_map_show_mode&1)
8144 {
8145 211510 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
8146 211510 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
8147 211510 }
8148
8149
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 213376 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
218976 if(view_map_show_mode&2 || r)
8150 213376 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
8151
8152
1/2
✓ Branch 0 taken 218976 times.
✗ Branch 1 not taken.
218976 if(r)
8153 {
8154 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
8155 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
8156 }
8157
8158 218976 advanceframe(false, false);
8159
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 189085 times.
218976 if (replay_version_check(11))
8160 189085 load_control_state();
8161
8162
2/2
✓ Branch 0 taken 217967 times.
✓ Branch 1 taken 1009 times.
218976 if (getInput(btnS, INPUT_PRESS | INPUT_IGNORE_DISABLE))
8163 1009 done = true;
8164
8165
2/2
✓ Branch 0 taken 217966 times.
✓ Branch 1 taken 1010 times.
437952 }
8166
2/2
✓ Branch 0 taken 1009 times.
✓ Branch 1 taken 217967 times.
218976 while(!done && !Quit);
8167
8168 1010 ViewingMap = false;
8169 1010 destroy_bitmap(mappic);
8170 1010 resume_all_sfx();
8171 1010 }
8172
8173 1112 int32_t onViewMap()
8174 {
8175
4/6
✓ Branch 0 taken 1112 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1112 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 1010 times.
1112 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
8176 {
8177 1010 clear_to_color(framebuf,BLACK);
8178 1010 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
8179 1010 advanceframe(true);
8180 1010 ViewMap();
8181 1010 }
8182
8183 1112 return D_O_K;
8184 }
8185
8186 38943734 bool isGrassType(int32_t type)
8187 {
8188
2/2
✓ Branch 0 taken 38185621 times.
✓ Branch 1 taken 758113 times.
38943734 switch(type)
8189 {
8190 case cTALLGRASS:
8191 case cTALLGRASSNEXT:
8192 case cTALLGRASSTOUCHY:
8193 758113 return true;
8194 }
8195
8196 38185621 return false;
8197 38943734 }
8198
8199 25672 bool isFlowersType(int32_t type)
8200 {
8201
2/2
✓ Branch 0 taken 21332 times.
✓ Branch 1 taken 4340 times.
25672 switch(type)
8202 {
8203 case cFLOWERS:
8204 case cFLOWERSTOUCHY:
8205 4340 return true;
8206 }
8207
8208 21332 return false;
8209 25672 }
8210
8211 bool isGenericType(int32_t type)
8212 {
8213 switch(type)
8214 {
8215 case cTRIGGERGENERIC:
8216 return true;
8217 }
8218
8219 return false;
8220 }
8221
8222 30978 bool isBushType(int32_t type)
8223 {
8224
2/2
✓ Branch 0 taken 25672 times.
✓ Branch 1 taken 5306 times.
30978 switch(type)
8225 {
8226 case cBUSH:
8227 case cBUSHNEXT:
8228 case cBUSHTOUCHY:
8229 case cBUSHNEXTTOUCHY:
8230
8231 5306 return true;
8232 }
8233
8234 25672 return false;
8235 30978 }
8236
8237 bool isSlashType(int32_t type)
8238 {
8239 switch(type)
8240 {
8241 case cSLASH:
8242 case cSLASHITEM:
8243 case cSLASHTOUCHY:
8244 case cSLASHITEMTOUCHY:
8245 case cSLASHNEXT:
8246 case cSLASHNEXTITEM:
8247 case cSLASHNEXTTOUCHY:
8248 case cSLASHNEXTITEMTOUCHY:
8249 return true;
8250 }
8251
8252 return false;
8253 }
8254
8255 18151 bool isCuttableNextType(int32_t type)
8256 {
8257
2/2
✓ Branch 0 taken 9830 times.
✓ Branch 1 taken 8321 times.
18151 switch(type)
8258 {
8259 case cSLASHNEXT:
8260 case cSLASHNEXTITEM:
8261 case cTALLGRASSNEXT:
8262 case cBUSHNEXT:
8263 case cSLASHNEXTTOUCHY:
8264 case cSLASHNEXTITEMTOUCHY:
8265 case cBUSHNEXTTOUCHY:
8266 8321 return true;
8267 }
8268
8269 9830 return false;
8270 18151 }
8271
8272 20007 bool isTouchyType(int32_t type)
8273 {
8274
2/2
✓ Branch 0 taken 8508 times.
✓ Branch 1 taken 11499 times.
20007 switch(type)
8275 {
8276 case cSLASHTOUCHY:
8277 case cSLASHITEMTOUCHY:
8278 case cBUSHTOUCHY:
8279 case cFLOWERSTOUCHY:
8280 case cTALLGRASSTOUCHY:
8281 case cSLASHNEXTTOUCHY:
8282 case cSLASHNEXTITEMTOUCHY:
8283 case cBUSHNEXTTOUCHY:
8284 11499 return true;
8285 }
8286
8287 8508 return false;
8288 20007 }
8289
8290 38867500 bool isCuttableType(int32_t type)
8291 {
8292
2/2
✓ Branch 0 taken 38414469 times.
✓ Branch 1 taken 453031 times.
38867500 switch(type)
8293 {
8294 case cSLASH:
8295 case cSLASHITEM:
8296 case cBUSH:
8297 case cFLOWERS:
8298 case cTALLGRASS:
8299 case cTALLGRASSNEXT:
8300 case cSLASHNEXT:
8301 case cSLASHNEXTITEM:
8302 case cBUSHNEXT:
8303
8304 case cSLASHTOUCHY:
8305 case cSLASHITEMTOUCHY:
8306 case cBUSHTOUCHY:
8307 case cFLOWERSTOUCHY:
8308 case cTALLGRASSTOUCHY:
8309 case cSLASHNEXTTOUCHY:
8310 case cSLASHNEXTITEMTOUCHY:
8311 case cBUSHNEXTTOUCHY:
8312 453031 return true;
8313 }
8314
8315 38414469 return false;
8316 38867500 }
8317
8318 19783 bool isCuttableItemType(int32_t type)
8319 {
8320
2/2
✓ Branch 0 taken 452 times.
✓ Branch 1 taken 19331 times.
19783 switch(type)
8321 {
8322 case cSLASHITEM:
8323 case cBUSH:
8324 case cFLOWERS:
8325 case cTALLGRASS:
8326 case cTALLGRASSNEXT:
8327 case cSLASHNEXTITEM:
8328 case cBUSHNEXT:
8329
8330 case cSLASHITEMTOUCHY:
8331 case cBUSHTOUCHY:
8332 case cFLOWERSTOUCHY:
8333 case cTALLGRASSTOUCHY:
8334 case cSLASHNEXTITEMTOUCHY:
8335 case cBUSHNEXTTOUCHY:
8336 19331 return true;
8337 }
8338
8339 452 return false;
8340 19783 }
8341
8342 69 bool is_push(mapscr* m, int32_t pos)
8343 {
8344
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if(is_push_flag(m->sflag[pos]))
8345 return true;
8346 69 newcombo const& cmb = combobuf[m->data[pos]];
8347
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 if(is_push_flag(cmb.flag))
8348 return true;
8349
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 55 times.
69 if(cmb.type == cPUSHBLOCK)
8350 14 return true;
8351
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 55 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
55 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8352 return true; //Counts as 'pushblock' flag
8353 55 return false;
8354 69 }
8355
8356 425 static std::map<int, screen_state_t> screen_states;
8357
8358 37528 std::map<int, screen_state_t>& get_screen_states()
8359 {
8360 37528 return screen_states;
8361 }
8362
8363 45806327 screen_state_t& get_screen_state(int screen)
8364 {
8365 45806327 return screen_states[screen];
8366 }
8367
8368 606 void clear_screen_states()
8369 {
8370 606 screen_states.clear();
8371 606 }
8372
8373 1597 void screen_item_set_state(int screen, ScreenItemState state)
8374 {
8375 1597 get_screen_state(screen).item_state = state;
8376 1597 }
8377
8378 557164 void mark_visited(int screen)
8379 {
8380
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 556689 times.
557164 if (screen < 0x80)
8381 {
8382
2/2
✓ Branch 0 taken 96919 times.
✓ Branch 1 taken 459770 times.
556689 if(DMaps[cur_dmap].flags&dmfVIEWMAP)
8383 459770 game->maps[mapind(cur_map, screen)] |= mVISITED;
8384
8385 556689 markBmap(-1, screen);
8386 556689 }
8387 557164 }
8388